結果
問題 | No.925 紲星 Extra |
ユーザー | chocorusk |
提出日時 | 2019-12-24 02:38:21 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 4,838 bytes |
コンパイル時間 | 1,234 ms |
コンパイル使用メモリ | 118,948 KB |
実行使用メモリ | 109,440 KB |
最終ジャッジ日時 | 2024-09-19 07:17:40 |
合計ジャッジ時間 | 23,144 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,376 KB |
testcase_02 | AC | 1 ms
5,376 KB |
testcase_03 | AC | 15 ms
5,376 KB |
testcase_04 | AC | 15 ms
5,376 KB |
testcase_05 | AC | 3,125 ms
108,672 KB |
testcase_06 | AC | 3,103 ms
109,440 KB |
testcase_07 | AC | 3,127 ms
108,928 KB |
testcase_08 | TLE | - |
testcase_09 | -- | - |
testcase_10 | -- | - |
testcase_11 | -- | - |
testcase_12 | -- | - |
testcase_13 | -- | - |
testcase_14 | -- | - |
testcase_15 | -- | - |
testcase_16 | -- | - |
testcase_17 | -- | - |
testcase_18 | -- | - |
testcase_19 | -- | - |
testcase_20 | -- | - |
testcase_21 | -- | - |
ソースコード
#include <cstdio> #include <cstring> #include <iostream> #include <string> #include <cmath> #include <bitset> #include <vector> #include <map> #include <set> #include <queue> #include <deque> #include <algorithm> #include <complex> #include <unordered_map> #include <unordered_set> #include <random> #include <cassert> #include <fstream> #include <utility> #include <functional> #include <time.h> #include <stack> #include <array> #define popcount __builtin_popcount using namespace std; typedef long long int ll; typedef pair<int, int> P; random_device rnd; mt19937 mt(rnd()); uniform_real_distribution<> rnd1(0, 1.0); struct node_t{ ll val; ll sum; node_t *lch; node_t *rch; double pri; int cnt; node_t() {} node_t(ll v, double p):val(v), sum(v), pri(p), cnt(1), lch(nullptr), rch(nullptr){} }; int count(node_t *t){ return !t ? 0 : t->cnt; } ll sum(node_t *t){ return !t ? 0 : t->sum; } node_t *update(node_t *t){ t->cnt=count(t->lch)+count(t->rch)+1; t->sum=sum(t->lch)+sum(t->rch)+t->val; return t; } node_t *merge(node_t *l, node_t *r){ if(!l || !r) return !l ? r : l; update(l); update(r); if(l->pri > r->pri){ l->rch=merge(l->rch, r); return update(l); }else{ r->lch=merge(l, r->lch); return update(r); } } pair<node_t*, node_t*> split(node_t *t, ll v){ //[0, v), [v, inf) if(!t) return make_pair(nullptr, nullptr); update(t); if(v <= t->val){ pair<node_t*, node_t*> s=split(t->lch, v); t->lch=s.second; return make_pair(s.first, update(t)); }else{ pair<node_t*, node_t*> s=split(t->rch, v); t->rch=s.first; return make_pair(update(t), s.second); } } pair<node_t*, node_t*> split2(node_t *t, int k){ //[0, k), [k,n) if(!t) return make_pair(nullptr, nullptr); update(t); if(k <= count(t->lch)){ pair<node_t*, node_t*> s=split2(t->lch, k); t->lch=s.second; return make_pair(s.first, update(t)); }else{ pair<node_t*, node_t*> s=split2(t->rch, k-1-count(t->lch)); t->rch=s.first; return make_pair(update(t), s.second); } } node_t *erase(node_t *t, ll v){ pair<node_t*, node_t*> s=split(t, v); pair<node_t*, node_t*> u=split2(s.second, 1); return merge(s.first, u.second); } node_t *insert(node_t *t, ll v){ pair<node_t*, node_t*> s=split(t, v); return merge(s.first, merge(new node_t(v, rnd1(mt)), s.second)); } void lower_bound(node_t *t, ll v, int &ret){ if(!t) return; if(v <= t->val) lower_bound(t->lch, v, ret); else{ ret+=count(t->lch)+1; lower_bound(t->rch, v, ret); } } void lower_sum(node_t *t, ll v, ll &ret){ if(!t) return; if(v <= t->val) lower_sum(t->lch, v, ret); else{ ret+=sum(t->lch)+t->val; lower_sum(t->rch, v, ret); } } template<typename T> struct BIT{ //1-indexed vector<T> bit; int size; BIT(){} BIT(int n):size(n), bit(n+1, 0){} void init(int n){ size=n; bit.resize(n+1, 0); } T sum(int i){ T s=0; while(i>0){ s+=bit[i]; i-=(i&(-i)); } return s; } void add(int i, T x){ while(i<=size){ bit[i]+=x; i+=(i&(-i)); } } }; int sz; node_t *seg[1<<17]; ll a[1<<16]; BIT<ll> bit; void update_query(int x, ll y){ int k=x+sz; seg[k]=erase(seg[k], a[x]); seg[k]=insert(seg[k], y); while(k>1){ k>>=1; seg[k]=erase(seg[k], a[x]); seg[k]=insert(seg[k], y); } bit.add(x+1, y-a[x]); a[x]=y; } int count_query(int l, int r, ll v){ l+=sz, r+=sz; int ret=0; for(;l<r;l>>=1, r>>=1){ if(r&1){ int ret1=0; lower_bound(seg[--r], v, ret1); ret+=ret1; } if(l&1){ int ret1=0; lower_bound(seg[l++], v, ret1); ret+=ret1; } } return ret; } ll sum_query(int l, int r, ll v){ l+=sz, r+=sz; ll ret=0; for(;l<r;l>>=1, r>>=1){ if(r&1){ ll ret1=0; lower_sum(seg[--r], v, ret1); ret+=ret1; } if(l&1){ ll ret1=0; lower_sum(seg[l++], v, ret1); ret+=ret1; } } return ret; } ll med(int l, int r){ ll al=0, ar=(1ll<<40); int m=(r-l)>>1; while(ar-al>1){ ll am=(al+ar)>>1; if(count_query(l, r, am)<=m) al=am; else ar=am; } return al; } ll query(int l, int r){ ll md=med(l, r); ll ret=-2*sum_query(l, r, md)+bit.sum(r)-bit.sum(l); if((r-l)&1) ret-=md; return ret; } int main() { int n, q; cin>>n>>q; for(int i=0; i<n; i++){ scanf("%lld", &a[i]); a[i]++; } sz=1; while(sz<n) sz<<=1; bit.init(n); for(int i=0; i<n; i++){ int k=i+sz; seg[k]=insert(seg[k], a[i]); while(k>1){ k>>=1; seg[k]=insert(seg[k], a[i]); } bit.add(i+1, a[i]); } ll p1=(1<<16)-1, p2=(1ll<<40)-1; ll s=0; for(int i=0; i<q; i++){ int t; scanf("%d", &t); if(t==1){ int x; ll y; scanf("%d %lld", &x, &y); x^=(s&p1); y^=(s&p2); update_query(x-1, y+1); }else{ int l, r; scanf("%d %d", &l, &r); l^=(s&p1); r^=(s&p1); if(l>r) swap(l, r); l--; ll ans=query(l, r); printf("%lld\n", ans); s^=ans; } } return 0; }