1. 程式人生 > 實用技巧 >[模板] 康託展開

[模板] 康託展開

[模板] 康託展開

給定\(1 - N\) 的一個全排列,試求它在所有\(1 -N\) 全排列中的排名

結果對\(998244353\)取模

程式碼

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;

ull readull(){
	ull x = 0;
	int f = 1;
	char ch = getchar();
	while(ch < '0' || ch > '9') {
		if(ch == '-') f = -1;
		ch = getchar(); 
	}
	while(ch >= '0' && ch <= '9'){
		x = x * 10 + ch - '0';
		ch = getchar();
	}
	return f * x;
}
int readint(){
	int x = 0;
	int f = 1;
	char ch = getchar();
	while(ch < '0' || ch > '9') {
		if(ch == '-') f = -1;
		ch = getchar(); 
	}
	while(ch >= '0' && ch <= '9'){
		x = x * 10 + ch - '0';
		ch = getchar();
	}
	return f * x;
}

const int maxn = 1e6 + 5;
const int MOD =  998244353;

int a[maxn];
int f[maxn];
int n;

struct BIT{
	int c[maxn];
	int ask(int x){
		int ans = 0;
		for(;x;x -= x & -x)
			ans += c[x];
		return ans;
	}
	void update(int x,int v){
		for(;x <= n;x += x & -x)
			c[x] += v;
	}
};

BIT bit;

int main(){
	n  = readint();
	for(int i = 0;i < n;i++)
		a[i] = readint();
	f[1] = 1;
	for(int i = 2;i < maxn - 3;i++)
		f[i] = (ll)f[i - 1] * i % MOD;
	int s = 0;
	for(int i = 0;i < n;i++){
		s = (s + (ll)f[n - i - 1] * (a[i] - 1 - bit.ask(a[i] - 1) + MOD) % MOD) % MOD;
		bit.update(a[i],1);
	}
	printf("%lld",(s + 1) % MOD);
}