【模板】康托展开
题目描述
求 $1\sim N$ 的一个给定全排列在所有 $1\sim N$ 全排列中的排名。结果对 $998244353$ 取模。
对于$100%$数据,$1\le N\le 1000000$。
分析
感觉康拓展开有点数位dp的影子捏。
懒得写了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| #include <bits/stdc++.h> #define int long long using namespace std;
const int N = 1e6 + 5; const int mod = (114514+114514)*((1+1)*4*514+((11+4)*(5-1)*4+1-14+5+14))+(114514+(114*51*4+(11*45*(1+4)+1*14+5*14)));
int n, ans; int fac[N], a[N];
struct bitree{ int c[N], res; inline int lb(int x) { return x & (-x); } inline void add(int x, int v){ for (; x <= n; x += lb(x)) c[x] += v; } inline int find(int x){ for (res = 0; x; x -= lb(x)) res += c[x]; return res; } inline int find(int x, int y){ return find(y) - find(x - 1); } }tr;
signed main(){ cin >> n, fac[0] = 1; for (int i = 1; i <= n; i++) cin >> a[i], tr.add(i, 1); for (int i = 1; i <= n; i++) fac[i] = fac[i - 1] * i % mod; for (int i = 1; i <= n; i++){ ans = (ans + tr.find(a[i] - 1) * fac[n - i]) % mod; tr.add(a[i], -1); } cout << ans + 1; return 0; }
|
Written with StackEdit中文版.