結果
問題 | No.925 紲星 Extra |
ユーザー | 👑 hos.lyric |
提出日時 | 2019-11-08 23:31:31 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 5,450 ms / 10,000 ms |
コード長 | 5,803 bytes |
コンパイル時間 | 1,815 ms |
コンパイル使用メモリ | 119,308 KB |
実行使用メモリ | 65,408 KB |
最終ジャッジ日時 | 2024-09-15 02:40:18 |
合計ジャッジ時間 | 69,123 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,376 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | AC | 14 ms
5,376 KB |
testcase_04 | AC | 15 ms
5,376 KB |
testcase_05 | AC | 3,964 ms
49,792 KB |
testcase_06 | AC | 4,034 ms
50,304 KB |
testcase_07 | AC | 3,957 ms
50,048 KB |
testcase_08 | AC | 3,778 ms
53,736 KB |
testcase_09 | AC | 3,459 ms
50,304 KB |
testcase_10 | AC | 4,302 ms
40,832 KB |
testcase_11 | AC | 4,425 ms
59,136 KB |
testcase_12 | AC | 3,913 ms
61,440 KB |
testcase_13 | AC | 2,162 ms
49,792 KB |
testcase_14 | AC | 3,572 ms
38,912 KB |
testcase_15 | AC | 2,170 ms
50,176 KB |
testcase_16 | AC | 5,080 ms
50,304 KB |
testcase_17 | AC | 5,450 ms
36,224 KB |
testcase_18 | AC | 4,749 ms
50,432 KB |
testcase_19 | AC | 4,878 ms
35,328 KB |
testcase_20 | AC | 4,007 ms
63,488 KB |
testcase_21 | AC | 1,898 ms
65,408 KB |
ソースコード
#pragma GCC optimize ("Ofast") #pragma GCC optimize ("unroll-loops") #pragma GCC target ("avx") #include <cassert> #include <cmath> #include <cstdint> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <bitset> #include <complex> #include <deque> #include <functional> #include <iostream> #include <map> #include <numeric> #include <queue> #include <set> #include <sstream> #include <string> #include <unordered_map> #include <unordered_set> #include <utility> #include <vector> using namespace std; using Int = long long; template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; }; template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; } template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; } template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; } namespace RBST { unsigned xrand() { static unsigned x = 314159265, y = 358979323, z = 846264338, w = 327950288; unsigned t = x ^ x << 11; x = y; y = z; z = w; return w = w ^ w >> 19 ^ t ^ t >> 8; } constexpr int MAX = 20000010; int n, l[MAX], r[MAX], size[MAX]; Int key[MAX], sum[MAX]; int node(Int key_) { n[l] = n[r] = -1; n[size] = 1; n[key] = n[sum] = key_; return n++; } int change(int a, int l_, int r_) { a[l] = l_; a[r] = r_; a[size] = (~l_ ? l_[size] : 0) + 1 + (~r_ ? r_[size] : 0); a[sum] = (~l_ ? l_[sum] : 0) + a[key] + (~r_ ? r_[sum] : 0); return a; } int merge(int a, int b) { if (!~a) return b; if (!~b) return a; if ((int)(xrand() % (a[size] + b[size])) < a[size]) { return change(a, a[l], merge(a[r], b)); } else { return change(b, merge(a, b[l]), b[r]); } } pair<int, int> splitKey(int a, Int key_) { if (!~a) return {-1, -1}; if (key_ <= a[key]) { const auto l_ = splitKey(a[l], key_); return {l_.first, change(a, l_.second, a[r])}; } else { const auto r_ = splitKey(a[r], key_); return {change(a, a[l], r_.first), r_.second}; } } pair<int, int> splitHead(int a) { if (~a[l]) { const auto l_ = splitHead(a[l]); return {l_.first, change(a, l_.second, a[r])}; } else { const int r_ = a[r]; return {change(a, -1, -1), r_}; } } int insert(int a, Int key_) { const auto sp = splitKey(a, key_); return merge(merge(sp.first, node(key_)), sp.second); } int eraseKey(int a, Int key_) { const auto sp = splitKey(a, key_); return merge(sp.first, splitHead(sp.second).second); } pair<int, Int> sumLessThan(int a, Int key_) { int ret0 = 0; Int ret1 = 0; for (; ~a; ) { if (key_ <= a[key]) { a = a[l]; } else { if (a[l]) { ret0 += a[l][size]; ret1 += a[l][sum]; } ret0 += 1; ret1 += a[key]; a = a[r]; } } return {ret0, ret1}; } void print(int a) { if (!~a) return; printf("["); print(a[l]); printf(" (%d;%lld) ", a, a[key]); print(a[r]); printf("]"); } } // RBST constexpr int MAX_N = 70010; constexpr int MASK_16 = (1 << 16) - 1; constexpr Int MASK_40 = (1LL << 40) - 1; int N, Q; Int A[MAX_N]; int segN; int seg[MAX_N << 2]; pair<int, Int> get(int a, int b) { int ret0 = 0; Int ret1 = 0; for (a += segN, b += segN; a < b; a >>= 1, b >>= 1) { if (a & 1) { ret0 += seg[a][RBST::size]; ret1 += seg[a][RBST::sum]; ++a; } if (b & 1) { --b; ret0 += seg[b][RBST::size]; ret1 += seg[b][RBST::sum]; } } return {ret0, ret1}; } pair<int, Int> get(int a, int b, Int key_) { int ret0 = 0; Int ret1 = 0; for (a += segN, b += segN; a < b; a >>= 1, b >>= 1) { if (a & 1) { const auto res = RBST::sumLessThan(seg[a++], key_); ret0 += res.first; ret1 += res.second; } if (b & 1) { const auto res = RBST::sumLessThan(seg[--b], key_); ret0 += res.first; ret1 += res.second; } } return {ret0, ret1}; } int main() { for (; ~scanf("%d%d", &N, &Q); ) { for (int i = 0; i < N; ++i) { scanf("%lld", &A[i]); } RBST::n = 0; for (segN = 1; segN < N; segN <<= 1) {} fill(seg, seg + (segN << 1), -1); for (int i = 0; i < N; ++i) { for (int a = segN + i; a; a >>= 1) { seg[a] = RBST::insert(seg[a], A[i]); } } // for(int a=1;a<segN<<1;++a){printf("seg[%d] = ",a);RBST::print(seg[a]);puts("");} Int s = 0; for (int q = 0; q < Q; ++q) { int typ; scanf("%d", &typ); switch (typ) { case 1: { int x; Int y; scanf("%d%lld", &x, &y); x ^= (s & MASK_16); y ^= (s & MASK_40); --x; // cerr<<"query 1 "<<x<<" "<<y<<endl; assert(0 <= x && x < N); for (int a = segN + x; a; a >>= 1) { seg[a] = RBST::insert(RBST::eraseKey(seg[a], A[x]), y); } A[x] = y; } break; case 2: { int l, r; scanf("%d%d", &l, &r); l ^= (s & MASK_16); r ^= (s & MASK_16); if (l > r) { swap(l, r); } --l; assert(0 <= l && l < r && r <= N); // cerr<<"query 2 "<<l<<" "<<r<<endl; Int lo = 0, hi = 1LL << 40; for (; lo + 1 < hi; ) { const Int mid = (lo + hi) / 2; ((get(l, r, mid).first >= (r - l + 1) / 2) ? hi : lo) = mid; } // cerr<<" lo = "<<lo<<endl; const auto all = get(l, r); const auto res = get(l, r, lo); Int ans = all.second - all.first * lo; ans -= 2 * (res.second - res.first * lo); printf("%lld\n", ans); s ^= ans; } break; default: assert(false); } } } return 0; }