1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
| #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cctype> #include<cstdio> #include<vector> #include<string> #include<queue> #include<stack> #include<cmath> #include<ctime> #include<map> #include<set> using namespace std; const int inf=0x7fffffff; const double eps=1e-10; const double pi=acos(-1.0);
inline int read(){ int x=0,f=1;char ch;ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-') f=0;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch&15);ch=getchar();} if(f)return x;else return -x; } const int N=1e5+10; struct fhq_treap{ #define lson ls[rt] #define rson rs[rt] int ls[N],rs[N]; bool lazy[N]; int lazy_w[N],val[N],key[N],size[N]; long long sum[N]; int root,cnt; int tmp[25],num[N][25]; void Xor(int rt,int x){ lazy_w[rt]^=x;val[rt]^=x; sum[rt]=0; for(int i=0;i<=20;++i)tmp[i]=(x>>i)&1; for(int i=0;i<=20;++i){ if(tmp[i])num[rt][i]=size[rt]-num[rt][i]; sum[rt]+=(1ll<<i)*num[rt][i]; } } void pushup(int rt){ size[rt]=size[lson]+size[rson]+1; sum[rt]=sum[lson]+sum[rson]+1ll*val[rt]; for(int i=0;i<=20;i++) num[rt][i]=num[lson][i]+num[rson][i]+((val[rt]>>i)&1); } void pushdown(int rt){ if(lazy[rt]){ swap(lson,rson); if(lson)lazy[lson]^=1; if(rson)lazy[rson]^=1; lazy[rt]=0; } if(lazy_w[rt]){ int x=lazy_w[rt];lazy_w[rt]=0; if(lson){Xor(lson,x);} if(rson){Xor(rson,x);} } } int merge(int a,int b){ if(!a||!b)return a|b; if(key[a]<key[b]){pushdown(a);rs[a]=merge(rs[a],b);pushup(a);return a;} else {pushdown(b);ls[b]=merge(a,ls[b]);pushup(b);return b;} } void split(int rt,int x,int &a,int &b){ if(!rt){a=b=0;return;} pushdown(rt); if(x<=size[lson]){b=rt;split(lson,x,a,lson);} else {a=rt;split(rson,x-size[lson]-1,rson,b);} pushup(rt); } int newnode(int x){ int rt=++cnt; size[rt]=1;val[rt]=x;key[rt]=rand(); lazy[rt]=0;lazy_w[rt]=0; lson=rson=0; return rt; } int build(int a[],int len){ stack<int> S; int rt,last; for(int i=1;i<=len;i++){ rt=newnode(a[i]);last=0; while(!S.empty()&&key[S.top()]>key[rt]) pushup(last=S.top()),S.pop(); if(!S.empty())rs[S.top()]=rt; lson=last;S.push(rt); } while(!S.empty())pushup(last=S.top()),S.pop(); return last; } void Revers(int l,int r){ int a,b,c; split(root,r,a,c); split(a,l-1,a,b); lazy[b]^=1; root=merge(merge(a,b),c); } void Update(int l,int r,int d){ int a,b,c; split(root,r,a,c); split(a,l-1,a,b); Xor(b,d); root=merge(merge(a,b),c); } long long Query(int l,int r){ int a,b,c; split(root,r,a,c); split(a,l-1,a,b); long long ret=sum[b]; root=merge(merge(a,b),c); return ret; } }Tree; int n,m; int a[N],op,l,r,d; int main() { srand(time(NULL)); n=read();m=read(); for(int i=1;i<=n;i++)a[i]=read(); Tree.root=Tree.build(a,n); while(m--){ op=read();l=read();r=read(); if(op==1)Tree.Revers(l,r); if(op==2)d=read(),Tree.Update(l,r,d); if(op==3)cout<<Tree.Query(l,r)<<endl; } return 0; }
|