题目
题解(D题)
数据结构题虽然难写,但是没什么好说的,具体看代码吧
Code
s
w
p
swp
swp是用来排序的,
t
o
t
tot
tot是用来统计答案的
t
r
i
e
trie
trie树内存要额外*
30
30
30
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200002;
int sz[N*30],t[N*30][30],c[N*30][2],tot,l,r,cnt,sum[N][30],n,i,num,tim,swp,a[N],m,op;
inline char gc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int rd(){
int x=0,fl=1;char ch=gc();
for(;ch<48||ch>57;ch=gc())if(ch=='-')fl=-1;
for(;48<=ch&&ch<=57;ch=gc())x=(x<<3)+(x<<1)+(ch^48);
return x*fl;
}
inline void wri(ll a){if(a<0)a=-a,putchar('-');if(a>=10)wri(a/10);putchar(a%10|48);}
inline void wln(ll a){wri(a),puts("");}
void ins(int x){
num++;int p=0;
for (int i=29;~i;i--){
if (!c[p][(x>>i)&1]) c[p][(x>>i)&1]=++tim;
p=c[p][(x>>i)&1],sz[p]++;
for (int j=0;j<30;j++) t[p][j]+=(x>>j)&1;
}
}
ll find(int k){
int p=0;ll res=0;
for (int i=29;~i;i--){
if (!k) return res;
int q=c[p][(swp>>i)&1];
if (k<sz[q]) p=q;
else{
k-=sz[q];
for (int j=0;j<30;j++)
if ((tot>>j)&1) res+=(ll)(sz[q]-t[q][j])<<j;
else res+=(ll)t[q][j]<<j;
p=c[p][((swp>>i)&1)^1];
}
}
for (int i=0;i<30;i++)
if (((tot>>i)&1)^(t[p][i]>0)) res+=(ll)k<<i;
return res;
}
ll query(int x){
if (x<=num) return find(x);
ll res=find(num);x-=num;
for (int i=0;i<30;i++)
if ((tot>>i)&1) res+=(ll)(x-sum[x][i])<<i;
else res+=(ll)sum[x][i]<<i;
return res;
}
void push(int x){
a[++cnt]=x;
for (int i=0;i<30;i++) sum[cnt][i]=sum[cnt-1][i]+((x>>i)&1);
}
void rebuild(){
while (cnt) ins(a[cnt--]);
swp=tot;
}
int main(){
n=rd();
for (i=1;i<=n;i++) push(rd());
for (m=rd();m--;){
op=rd();
if (op==1) push(rd()^tot);
if (op==2) l=rd(),r=rd(),wln(query(r)-query(l-1));
if (op==3) tot^=rd();
if (op==4) rebuild();
}
}