P3014 [USACO11FEB]Cow Line S
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 107 108 109 110 111
| #include<bits/stdc++.h> using namespace std; #define int long long const int MAXn = 20;
template <typename T> inline void read(T &a) { char c;for (c = getchar(); (c < '0' || c > '9') && c != '-'; c = getchar());bool f = c == '-';T x = f ? 0 : c ^ '0';for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) {x = x * 10 + (c ^ '0');}a = f ? -x : x; } template <typename T, typename ...Argv> inline void read(T &a, Argv &...argv) { read(a), read(argv...); }
int t[MAXn + 10]; inline int lowbit(int x) { return x & (-x); } inline void BuildUseSum(int *sum, int top) { for (int i = 1; i <= top; ++i) { t[i] = sum[i] - sum[i - lowbit(i)]; } } inline void Add(int p, int x, int top) { while (p <= top) { t[p] += x; p += lowbit(p); } } inline int Sum(int p) { int ans = 0; while (p) { ans += t[p]; p -= lowbit(p); } return ans; } inline int Div(int l, int r, int x) { int mid; while (l < r) { mid = (l + r) >> 1; if (Sum(mid) >= x) { r = mid; } else { l = mid + 1; } } return l; }
int fac[MAXn + 10]; void EvaFac(int top) { fac[0] = 1; for (int i = 1; i <= top; ++i) { fac[i] = fac[i - 1] * i; } } int sum[MAXn + 10]; void EvaSum(int top) { for (int i = 1; i <= top; ++i) { sum[i] = i; } }
int n, q; int x, a[MAXn + 10]; int cnt[MAXn + 10], ans[MAXn + 10]; void InvCantor() { BuildUseSum(sum, n); int tmpx = x - 1; for (int i = n; i; --i) { cnt[i] = tmpx / fac[i - 1]; tmpx %= fac[i - 1]; } for (int i = n; i; --i) { ans[i] = Div(1, n, cnt[i] + 1); Add(ans[i], -1, n); } } int Cantor() { BuildUseSum(sum, n); int ans = 1; for (int i = n; i; --i) { Add(a[i], -1, n); ans += fac[i - 1] * Sum(a[i]); } return ans; }
signed main() { read(n, q); EvaFac(n); EvaSum(n); char opt; for (int i = 1; i <= q; ++i) { cin >> opt; if (opt == 'P') { read(x); InvCantor(); for (int i = n; i; --i) { printf("%lld ", ans[i]); } puts(""); } else { for (int i = n; i; --i) { read(a[i]); } printf("%lld\n", Cantor()); } } }
|