其他分享
首页 > 其他分享> > 康托展开

康托展开

作者:互联网

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