Codeforces 396D

题意略。

思路:

很经典的逆序对计数问题。

https://blog.csdn.net/v5zsq/article/details/79006684

这篇博客讲得很好。

当循环到n的时候,我们需要特殊考虑,因为在循环内,它的贡献为0,所以我们在出循环的时候,还要特殊地加上一个值,也即整体的逆序对个数。

详见代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod = 1e9 + 7;
const int maxn = 1e6 + 5;

int p[maxn],n;
LL fac[maxn],f[maxn],BIT[maxn];

void init(){
    fac[0] = fac[1] = 1;
    for(LL i = 2;i < maxn;++i){
        fac[i] = i * fac[i - 1] % mod;
        LL C = i * (i - 1) / 2 % mod;
        f[i] = C * C % mod * fac[i - 2] % mod;
    }
}
int lowbit(int k){
    return k & -k;
}
void add(int pos,LL val){
    while(pos <= n){
        BIT[pos] += val;
        pos += lowbit(pos);
    }
}
LL sum(int pos){
    LL ret = 0;
    while(pos > 0){
        ret += BIT[pos];
        pos -= lowbit(pos);
    }
    return ret;
}

int main(){
    init();
    while(scanf("%d",&n) == 1){
        memset(BIT,0,sizeof(BIT));
        for(int i = 1;i <= n;++i) scanf("%d",&p[i]);
        LL ans = 0,s = 0;
        for(int i = 1;i <= n;++i){
            LL useful = p[i] - 1 - sum(p[i]);
            ans = (ans + s * useful % mod * fac[n - i] % mod) % mod;
            ans = (ans + useful * f[n - i] % mod) % mod;
            ans = (ans + useful * (useful - 1) / 2 % mod * fac[n - i] % mod) % mod;
            s += useful;
            s %= mod;
            add(p[i],1);
        }
        ans = (ans + s) % mod;
        printf("%lld\n",ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/tiberius/p/9426122.html