康托展开
作者:互联网
https://www.luogu.com.cn/problem/P5367
给定一个全排列,求出它是 1 ~ \(n\) 所有全排列的第几个,答案对 998244353 取模。
答案就是 \(\sum_{i = 1}^{n} res_{a_i} (n - i)!\)。\(res_x\) 表示剩下的比 \(x\) 小的数字的数量,通过树状数组处理。
代码:
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int mod = 998244353, N = 1e6 + 10;
LL fact[N];
struct fwt{
LL n;
vector <LL> a;
fwt(LL n) : n(n), a(n + 1) {}
LL sum(LL x){
LL res = 0;
for (; x; x -= x & -x)
res += a[x];
return res;
}
void add(LL x, LL k){
for (; x <= n; x += x & -x)
a[x] += k;
}
LL query(LL x, LL y){
return sum(y) - sum(x - 1);
}
};
int main(){
ios::sync_with_stdio(false);cin.tie(0);
LL n;
cin >> n;
fwt a(n);
fact[0] = 1;
for (int i = 1; i <= n; i ++ ){
fact[i] = fact[i - 1] * i % mod;
a.add(i, 1);
}
LL ans = 0;
for (int i = 1; i <= n; i ++ ){
LL x;
cin >> x;
ans = (ans + a.query(1, x - 1) * fact[n - i] % mod ) % mod;
a.add(x, -1);
}
cout << (ans + 1) % mod << "\n";
return 0;
}
标签:res,LL,ans,fwt,康托,展开,fact,mod 来源: https://www.cnblogs.com/Hamine/p/16320683.html