結果
問題 | No.1371 交換門松列・松 |
ユーザー | hashiryo |
提出日時 | 2023-10-30 12:49:41 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 470 ms / 4,000 ms |
コード長 | 4,316 bytes |
コンパイル時間 | 2,830 ms |
コンパイル使用メモリ | 217,664 KB |
実行使用メモリ | 11,348 KB |
最終ジャッジ日時 | 2024-09-25 17:13:52 |
合計ジャッジ時間 | 10,351 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,812 KB |
testcase_01 | AC | 2 ms
6,940 KB |
testcase_02 | AC | 2 ms
6,944 KB |
testcase_03 | AC | 2 ms
6,944 KB |
testcase_04 | AC | 2 ms
6,944 KB |
testcase_05 | AC | 2 ms
6,944 KB |
testcase_06 | AC | 2 ms
6,940 KB |
testcase_07 | AC | 2 ms
6,944 KB |
testcase_08 | AC | 2 ms
6,940 KB |
testcase_09 | AC | 2 ms
6,940 KB |
testcase_10 | AC | 2 ms
6,940 KB |
testcase_11 | AC | 2 ms
6,940 KB |
testcase_12 | AC | 2 ms
6,940 KB |
testcase_13 | AC | 2 ms
6,944 KB |
testcase_14 | AC | 2 ms
6,940 KB |
testcase_15 | AC | 2 ms
6,940 KB |
testcase_16 | AC | 2 ms
6,940 KB |
testcase_17 | AC | 2 ms
6,944 KB |
testcase_18 | AC | 303 ms
11,224 KB |
testcase_19 | AC | 301 ms
11,348 KB |
testcase_20 | AC | 310 ms
11,348 KB |
testcase_21 | AC | 299 ms
11,348 KB |
testcase_22 | AC | 297 ms
11,348 KB |
testcase_23 | AC | 454 ms
11,220 KB |
testcase_24 | AC | 461 ms
11,220 KB |
testcase_25 | AC | 449 ms
11,344 KB |
testcase_26 | AC | 450 ms
11,348 KB |
testcase_27 | AC | 464 ms
11,220 KB |
testcase_28 | AC | 465 ms
11,220 KB |
testcase_29 | AC | 458 ms
11,312 KB |
testcase_30 | AC | 470 ms
11,224 KB |
testcase_31 | AC | 463 ms
11,344 KB |
ソースコード
// #define _GLIBCXX_DEBUG #include <bits/stdc++.h> // clang-format off std::ostream&operator<<(std::ostream&os,std::int8_t x){return os<<(int)x;} std::ostream&operator<<(std::ostream&os,std::uint8_t x){return os<<(int)x;} std::ostream&operator<<(std::ostream&os,const __int128_t &v){if(!v)os<<"0";__int128_t tmp=v<0?(os<<"-",-v):v;std::string s;while(tmp)s+='0'+(tmp%10),tmp/=10;return std::reverse(s.begin(),s.end()),os<<s;} std::ostream&operator<<(std::ostream&os,const __uint128_t &v){if(!v)os<<"0";__uint128_t tmp=v;std::string s;while(tmp)s+='0'+(tmp%10),tmp/=10;return std::reverse(s.begin(),s.end()),os<<s;} #define checkpoint() (void(0)) #define debug(...) (void(0)) #define debugArray(x,n) (void(0)) #define debugMatrix(x,h,w) (void(0)) // clang-format on template <class T= long long> class WaveletMatrix { struct SuccinctIndexableDictionary { std::size_t len, blocks, zeros; std::vector<unsigned> bit, sum; SuccinctIndexableDictionary()= default; SuccinctIndexableDictionary(std::size_t len): len(len), blocks((len >> 5) + 1), bit(blocks, 0), sum(blocks, 0) {} void set(int k) { bit[k >> 5]|= 1U << (k & 31); } void build() { for (std::size_t i= 1; i < blocks; i++) sum[i]= sum[i - 1] + __builtin_popcount(bit[i - 1]); zeros= rank0(len); } bool operator[](int k) const { return (bit[k >> 5] >> (k & 31)) & 1; } std::size_t rank(std::size_t k) const { return (sum[k >> 5] + __builtin_popcount(bit[k >> 5] & ((1U << (k & 31)) - 1))); } std::size_t rank0(std::size_t k) const { return k - rank(k); } }; std::size_t len, lg; std::vector<SuccinctIndexableDictionary> mat; std::vector<T> vec; public: WaveletMatrix()= default; WaveletMatrix(const std::vector<T> &v): len(v.size()), lg(32 - __builtin_clz(std::max<int>(len, 1))), mat(lg, len), vec(v) { std::sort(vec.begin(), vec.end()); vec.erase(std::unique(vec.begin(), vec.end()), vec.end()); std::vector<unsigned> cur(len), nex(len); for (int i= len; i--;) cur[i]= std::lower_bound(vec.begin(), vec.end(), v[i]) - vec.begin(); for (auto h= lg; h--; cur.swap(nex)) { for (std::size_t i= 0; i < len; i++) if ((cur[i] >> h) & 1) mat[h].set(i); mat[h].build(); std::array it{nex.begin(), nex.begin() + mat[h].zeros}; for (std::size_t i= 0; i < len; i++) *it[mat[h][i]]++= cur[i]; } } // k-th(0-indexed) smallest number in v[l,r) T kth_smallest(int l, int r, int k) const { assert(k < r - l); std::size_t ret= 0; for (auto h= lg; h--;) if (auto l0= mat[h].rank0(l), r0= mat[h].rank0(r); k >= r0 - l0) { k-= r0 - l0, ret|= 1 << h; l+= mat[h].zeros - l0, r+= mat[h].zeros - r0; } else l= l0, r= r0; return vec[ret]; } // k-th(0-indexed) largest number in v[l,r) T kth_largest(int l, int r, int k) const { return kth_smallest(l, r, r - l - k - 1); } // count i s.t. (l <= i < r) && (v[i] < ub) std::size_t count(int l, int r, T ub) const { std::size_t x= std::lower_bound(vec.begin(), vec.end(), ub) - vec.begin(); if (x >= 1u << lg) return r - l; if (x == 0) return 0; std::size_t ret= 0; for (auto h= lg; h--;) if (auto l0= mat[h].rank0(l), r0= mat[h].rank0(r); (x >> h) & 1) ret+= r0 - l0, l+= mat[h].zeros - l0, r+= mat[h].zeros - r0; else l= l0, r= r0; return ret; } // count i s.t. (l <= i < r) && (lb <= v[i] < ub) std::size_t count(int l, int r, T lb, T ub) const { return count(l, r, ub) - count(l, r, lb); } }; using namespace std; signed main() { cin.tie(0); ios::sync_with_stdio(0); int N; cin >> N; vector<int> A(N); for (int i= 0; i < N; ++i) cin >> A[i], --A[i]; if (A[0] < A[1]) for (auto &x: A) x= N - 1 - x; vector<int> B(N); for (int i= 0; i < N; ++i) { if (i & 1) { B[i]= A[i - 1]; if (i + 1 < N) B[i]= min(B[i], A[i + 1]); } else { B[i]= 0; if (i) B[i]= max(B[i], A[i - 1]); if (i + 1 < N) B[i]= max(B[i], A[i + 1]); } } debug(A, B); vector<int> ve(N, -1), vo(N, -1); for (int i= 0; i < N; ++i) { if (i & 1) vo[A[i]]= B[i]; else ve[A[i]]= B[i]; } WaveletMatrix<int> wme(ve), wmo(vo); long long ans= 0; for (int i= 0; i < N; ++i) { if (i & 1) { ans+= wme.count(0, B[i], 0, A[i]); ans+= wmo.count(0, B[i], A[i] + 1, N); } else { ans+= wme.count(B[i] + 1, N, 0, A[i]); ans+= wmo.count(B[i] + 1, N, A[i] + 1, N); } } ans= (ans - N) / 2; cout << ans << '\n'; return 0; }