[模板] 康託展開
阿新 • • 發佈:2020-11-05
[模板] 康託展開
給定\(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); }