1 条题解
-
0
#include <bits/stdc++.h> #define int long long using namespace std; const int MOD = 998244353; const int MAXN = 1000000; int n; int a[MAXN + 5]; // 纯暴力按字典序枚举排列,看第几个是输入的(5分) namespace subtask1 { vector<int> now; bool check() { for (int i = 1; i <= n; i++) if (a[i] != now[i - 1]) return false; return true; } void work() { for (int i = 1; i <= n; i++) now.push_back(i); int cnt = 1; do { if (check()) { cout << cnt << "\n"; return; } cnt++; } while (next_permutation(now.begin(), now.end())); } } // 暴力康托展开(20分) namespace subtask2 { int fact[MAXN + 5]; // i! bool vis[MAXN + 5]; // i是否还在 // 判断1~x-1还存在几个数 int cnt(int x) { int res = 0; for (int i = 1; i <= x - 1; i++) res += vis[i]; return res; } void work() { fact[0] = 1; for (int i = 1; i <= n; i++) fact[i] = fact[i - 1] * i % MOD, vis[i] = true; int res = 1; for (int i = 1; i <= n; i++) { res = (res + cnt(a[i]) * fact[n - i] % MOD) % MOD; //cout << a[i] << "~" << cnt(a[i]) << "~" << fact[n - i] << endl; vis[a[i]] = false; } cout << res << "\n"; } } //树状数组优化康托展开 namespace subtask3 { int fact[MAXN + 5]; // i! int t[MAXN + 5]; int lowbit(int x) { return x & (-x); } void add(int pos, int x) { for (int i = pos; i <= n; i += lowbit(i)) t[i] += x; } int query(int pos) { int res = 0; for (int i = pos; i >= 1; i -= lowbit(i)) res += t[i]; return res; } void work() { fact[0] = 1; for (int i = 1; i <= n; i++) fact[i] = fact[i - 1] * i % MOD, add(i, 1); int res = 1; for (int i = 1; i <= n; i++) { res = (res + query(a[i] - 1) * fact[n - i] % MOD) % MOD; add(a[i], -1); } cout << res << "\n"; } } signed main() { ios::sync_with_stdio(false); cin.tie(0); cin >> n; for (int i = 1; i <= n; i++) cin >> a[i]; if (n <= 10) subtask1::work(); else if (n <= 5000) subtask2::work(); else subtask3::work(); return 0; }
- 1
信息
- ID
- 1273
- 时间
- 1000ms
- 内存
- 64MiB
- 难度
- 6
- 标签
- 递交数
- 37
- 已通过
- 12
- 上传者