最近突然放棄治療開始隨機跳題了node
感受還行c++
就是必須吸氧感受有點糟糕。。。spa
這題翻轉和求和都是平衡樹基本操做,那個異或能夠經過維護樹中\(2\)進制下第\(2^{i}\)位的\(1\)的個數,便可\(O(\log d)\)快速維護code
當敲板子玩了get
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define enter putchar('\n') #define eps 1e-10 #define ba 47 #define MAXN 100005 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; template<class T> void read(T &res) { res = 0;T f = 1;char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { res = res * 10 +c - '0'; c = getchar(); } res *= f; } template<class T> void out(T x) { if(x < 0) {x = -x;putchar('-');} if(x >= 10) { out(x / 10); } putchar('0' + x % 10); } mt19937 rnd(20020328); struct node { int pri; int lc,rc,siz; int cnt[20],d; int64 sum,val; bool rev; }tr[MAXN]; int N,M,rt; int a[MAXN]; #define lc(u) tr[u].lc #define rc(u) tr[u].rc #define sum(u) tr[u].sum void update(int u) { for(int j = 0 ; j < 20 ; ++j) { tr[u].cnt[j] = ((tr[u].val >> j) & 1) + tr[lc(u)].cnt[j] + tr[rc(u)].cnt[j]; } tr[u].sum = tr[u].val + tr[lc(u)].sum + tr[rc(u)].sum; tr[u].siz = 1 + tr[lc(u)].siz + tr[rc(u)].siz; } void xorit(int u,int d) { tr[u].val ^= d;tr[u].d ^= d; for(int j = 0 ; j < 20 ; ++j) { if(d >> j & 1) { tr[u].sum -= 1LL * tr[u].cnt[j] * (1 << j); tr[u].sum += 1LL * (tr[u].siz - tr[u].cnt[j]) * (1 << j); tr[u].cnt[j] = tr[u].siz - tr[u].cnt[j]; } } } void Rev(int u) { tr[u].rev ^= 1; swap(lc(u),rc(u)); } void pushdown(int u) { if(tr[u].d) { if(lc(u)) xorit(lc(u),tr[u].d); if(rc(u)) xorit(rc(u),tr[u].d); tr[u].d = 0; } if(tr[u].rev) { if(lc(u)) Rev(lc(u)); if(rc(u)) Rev(rc(u)); tr[u].rev = 0; } } int Merge(int u,int v) { if(!u) return v; if(!v) return u; pushdown(u);pushdown(v); if(tr[u].pri > tr[v].pri) { tr[u].rc = Merge(tr[u].rc,v); update(u); return u; } else { tr[v].lc = Merge(u,tr[v].lc); update(v); return v; } } void Split(int u,int &L,int &R,int s) { if(u == 0) {L = R = 0;return;} int t = tr[lc(u)].siz + 1; pushdown(u); if(s >= t) { L = u; Split(tr[u].rc,tr[L].rc,R,s - t); update(L); } else { R = u; Split(tr[u].lc,L,tr[R].lc,s); update(R); } } void Modify(int l,int r,int d) { int L,R,p; Split(rt,L,R,l - 1); Split(R,p,R,r - l + 1); xorit(p,d); rt = Merge(L,p);rt = Merge(rt,R); } void Rev_Range(int l,int r) { int L,R,p; Split(rt,L,R,l - 1); Split(R,p,R,r - l + 1); Rev(p); rt = Merge(L,p);rt = Merge(rt,R); } int64 Query(int l,int r) { int L,R,p; Split(rt,L,R,l - 1); Split(R,p,R,r - l + 1); int64 res = tr[p].sum; rt = Merge(L,p);rt = Merge(rt,R); return res; } void Solve() { read(N);read(M); for(int i = 1 ; i <= N ; ++i) { read(a[i]); tr[i].pri = rnd();tr[i].sum = a[i];tr[i].val = a[i]; for(int j = 0 ; j < 20 ; ++j) { tr[i].cnt[j] = (a[i] >> j) & 1; } tr[i].siz = 1; rt = Merge(rt,i); } int opt,l,r,d; for(int i = 1 ; i <= M ; ++i) { read(opt);read(l);read(r); if(opt == 1) Rev_Range(l,r); else if(opt == 2) {read(d);Modify(l,r,d);} else {out(Query(l,r));enter;} } } int main(){ #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }