結果
問題 | No.696 square1001 and Permutation 5 |
ユーザー |
|
提出日時 | 2020-07-30 20:33:05 |
言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
結果 |
TLE
(最新)
AC
(最初)
|
実行時間 | - |
コード長 | 3,478 bytes |
コンパイル時間 | 5,901 ms |
コンパイル使用メモリ | 116,004 KB |
最終ジャッジ日時 | 2025-01-12 08:13:01 |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 11 TLE * 1 |
ソースコード
#include <algorithm>#include <cmath>#include <cstdint>#include <cstdio>#include <map>#include <vector>using namespace std;using u64 = uint64_t;template <class T>class BIT {int N;vector<T> dat;public:explicit BIT(int n) : N(n+2), dat(N) {}void add(int k, T x) {for(int i=k+1; i<N; i+=i&-i) { dat[i] += x; }}T sum(int k) {T res = 0;for(int i=k; i; i-=i&-i) { res += dat[i]; }return res;}};inline constexpr int BASE_DIGITS = 7,BASE = static_cast<int>(powl(10, BASE_DIGITS));inline constexpr u64 O = 7,M = (1ULL << 63) - (1ULL << 41) + 1,M2 = M - 2;inline constexpr u64 mod_mul(__uint128_t x, u64 y) {return static_cast<u64>(x * y % M);}map<pair<u64, u64>, u64> cache;inline u64 mod_pow(u64 a, u64 n) {auto key = make_pair(a, n);if(cache.count(key)) { return cache[key]; }u64 res = 1;for(; n; n>>=1) {if(n & 1) { res = mod_mul(res, a); }a = mod_mul(a, a);}return cache[key] = res;}void myfmt(vector<u64> &a, bool inv) {size_t n = a.size();if(n == 1) { return; }size_t m = n / 2;vector<u64> a0(m), a1(m);for(size_t i=0, j=0; i<m; ++i) {a0[i] = a[j++];a1[i] = a[j++];}myfmt(a0, inv);myfmt(a1, inv);u64 z = mod_pow(O, (M-1)/n);if(inv) { z = mod_pow(z, M2); }u64 pz = 1;for(size_t i=0, k=0; k<m; ++i, ++k) {a[k] = a0[i] + mod_mul(a1[i], pz);if(a[k] >= M) { a[k] -= M; }pz = mod_mul(pz, z);}for(size_t i=0, k=m; k<n; ++i, ++k) {a[k] = a0[i] + mod_mul(a1[i], pz);if(a[k] >= M) { a[k] -= M; }pz = mod_mul(pz, z);}}void fmt(vector<u64> &a) {myfmt(a, false);}void ifmt(vector<u64> &a) {myfmt(a, true);size_t n = a.size();u64 inv = mod_pow(n, M2);for(size_t i=0; i<n; ++i) {a[i] = mod_mul(a[i], inv);}}vector<u64> convol(const vector<u64> &A, const vector<u64> &B) {vector<u64> a = A, b = B;size_t n = 1;while(n < a.size() + b.size()) { n <<= 1; }a.resize(n);b.resize(n);fmt(a);fmt(b);vector<u64> c(n);for(size_t i=0; i<n; ++i) {c[i] = mod_mul(a[i], b[i]);}ifmt(c);for(size_t i=0; i<n-1; ++i) {c[i+1] += c[i] / BASE;c[i] %= BASE;}while(c.back() == 0 && n > 1) { c.pop_back(); --n; }return c;}vector<u64> add(const vector<u64> &A, const vector<u64> &B) {vector<u64> a = A, b = B;size_t N = max(a.size(), b.size());a.resize(N);b.resize(N);vector<u64> c(N);for(size_t i=0; i<N; ++i) {c[i] = a[i] + b[i];}for(size_t i=0; i<N-1; ++i) {c[i+1] += c[i] / BASE;c[i] %= BASE;}return c;}vector<u64> v;pair<vector<u64>, vector<u64>> f(int lo, int hi) {if(hi - lo == 1) { return {{v[lo]}, {static_cast<u64>(lo+1)}}; }int md = (lo + hi) / 2;auto [x0, x1] = f(lo, md);auto [y0, y1] = f(md, hi);return {add(convol(y0, x1), x0), convol(x1, y1)};}void print(vector<u64> &a) {size_t n = a.size();reverse(a.begin(), a.end());printf("%lu", a[0]);for(size_t i=1; i<n; ++i) {printf("%0*lu", BASE_DIGITS, a[i]);}putchar('\n');}int main(void) {int N; scanf("%d", &N);BIT<int> tree(N);v.resize(N);vector<int> p(N);for(int i=0; i<N; ++i) {scanf("%d", &p[i]);tree.add(--p[i], 1);}for(int i=0; i<N; ++i) {v[N-1-i] = tree.sum(p[i]);tree.add(p[i], -1);}vector<u64> r = add(f(0, N).first, vector<u64>(1, 1));print(r);return 0;}