#include <bits/stdc++.h> using namespace std; struct node { int inv; long long cnt; node(int inv = 1234, long long cnt = 0) : inv(inv), cnt(cnt) { } node& operator+=(const node& o) { if (inv > o.inv) { *this = o; } else if (inv == o.inv) { cnt += o.cnt; } return *this; } }; struct hash_table { static constexpr int P = 4782971; int ec, head[P], nxt[P]; long long to[P]; node value[P]; node& operator[](long long v) { for (int e = head[v % P]; e; e = nxt[e]) { if (to[e] == v) { return value[e]; } } ++ec; to[ec] = v; nxt[ec] = head[v % P]; head[v % P] = ec; value[ec] = node(); return value[ec]; }; void clear() { for (int e = 1; e <= ec; ++e) { head[to[e] % P] = 0; } ec = 0; } }; int main() { #ifdef LOCAL freopen("input.txt", "r", stdin); #endif ios::sync_with_stdio(false); cin.tie(0); int n; cin >> n; vector<int> a(n); for (int i = 0; i < n; ++i) { cin >> a[i]; --a[i]; } a.push_back(n); vector<hash_table> dp(2); dp[0][0] += node(0, 1); for (int i = 0, o = 0; i < n; ++i, o = !o) { unordered_map<long long, node> new_dp; vector<int> b = a; sort(b.begin() + i + 1, b.end()); int l = 0; int r = n; for (int j = i + 1; j < n; ++j) { if (b[j] < a[i]) { l = max(l, b[j] + 1); } else { r = min(r, b[j]); } } auto skip = [&](long long state, node value) { long long mid = (state & ((1ll << r) - 1)) >> l; state ^= mid << l; state ^= ((1ll << __builtin_popcountll(mid)) - 1) << l; dp[!o][state] += value; }; auto take = [&](long long state, node value) { value.inv += __builtin_popcountll(state >> a[i]); state |= 1ll << a[i]; skip(state, value); }; for (int e = 1; e <= dp[o].ec; ++e) { skip(dp[o].to[e], dp[o].value[e]); take(dp[o].to[e], dp[o].value[e]); } dp[o].clear(); } vector<node> ans(n + 1); int o = n & 1; for (int e = 1; e <= dp[o].ec; ++e) { ans[__builtin_popcountll(dp[o].to[e])] += dp[o].value[e]; } for (int i = 1; i <= n; ++i) { cout << ans[i].inv << " " << ans[i].cnt << "\n"; } return 0; }
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 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | #include <bits/stdc++.h> using namespace std; struct node { int inv; long long cnt; node(int inv = 1234, long long cnt = 0) : inv(inv), cnt(cnt) { } node& operator+=(const node& o) { if (inv > o.inv) { *this = o; } else if (inv == o.inv) { cnt += o.cnt; } return *this; } }; struct hash_table { static constexpr int P = 4782971; int ec, head[P], nxt[P]; long long to[P]; node value[P]; node& operator[](long long v) { for (int e = head[v % P]; e; e = nxt[e]) { if (to[e] == v) { return value[e]; } } ++ec; to[ec] = v; nxt[ec] = head[v % P]; head[v % P] = ec; value[ec] = node(); return value[ec]; }; void clear() { for (int e = 1; e <= ec; ++e) { head[to[e] % P] = 0; } ec = 0; } }; int main() { #ifdef LOCAL freopen("input.txt", "r", stdin); #endif ios::sync_with_stdio(false); cin.tie(0); int n; cin >> n; vector<int> a(n); for (int i = 0; i < n; ++i) { cin >> a[i]; --a[i]; } a.push_back(n); vector<hash_table> dp(2); dp[0][0] += node(0, 1); for (int i = 0, o = 0; i < n; ++i, o = !o) { unordered_map<long long, node> new_dp; vector<int> b = a; sort(b.begin() + i + 1, b.end()); int l = 0; int r = n; for (int j = i + 1; j < n; ++j) { if (b[j] < a[i]) { l = max(l, b[j] + 1); } else { r = min(r, b[j]); } } auto skip = [&](long long state, node value) { long long mid = (state & ((1ll << r) - 1)) >> l; state ^= mid << l; state ^= ((1ll << __builtin_popcountll(mid)) - 1) << l; dp[!o][state] += value; }; auto take = [&](long long state, node value) { value.inv += __builtin_popcountll(state >> a[i]); state |= 1ll << a[i]; skip(state, value); }; for (int e = 1; e <= dp[o].ec; ++e) { skip(dp[o].to[e], dp[o].value[e]); take(dp[o].to[e], dp[o].value[e]); } dp[o].clear(); } vector<node> ans(n + 1); int o = n & 1; for (int e = 1; e <= dp[o].ec; ++e) { ans[__builtin_popcountll(dp[o].to[e])] += dp[o].value[e]; } for (int i = 1; i <= n; ++i) { cout << ans[i].inv << " " << ans[i].cnt << "\n"; } return 0; } |