又一部SCOI血泪史。。。。
唉。
就是在这棵树上一遍又一遍跑嘛。
以后不要直接求答案啊。要最后再异或起来。
要学习简单的代码风格。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 200500 #define maxm 4005000 #define inf 262143 using namespace std; int n,m,a[maxn],root[maxn],tot=0,tree[maxm][3],sum[maxm]; int b,x,l,r; void insert(int last,int &now,int left,int right,int p) { now=++tot; tree[now][1]=tree[last][1];tree[now][2]=tree[last][2]; sum[now]=sum[last]+1; if (left==right) return; int mid=(left+right)>>1; if (p<=mid) insert(tree[last][1],tree[now][1],left,mid,p); else insert(tree[last][2],tree[now][2],mid+1,right,p); } bool query(int last,int now,int left,int right,int l,int r) { if ((left==l) && (right==r)) return sum[now]-sum[last]>0; int mid=(left+right)>>1; if (r<=mid) return query(tree[last][1],tree[now][1],left,mid,l,r); else if (l>=mid+1) return query(tree[last][2],tree[now][2],mid+1,right,l,r); else return query(tree[last][1],tree[now][1],left,mid,l,mid)||query(tree[last][2],tree[now][2],mid+1,right,mid+1,r); } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d",&a[i]); for (int i=1;i<=n;i++) insert(root[i-1],root[i],0,inf,a[i]); for (int i=1;i<=m;i++) { scanf("%d%d%d%d",&b,&x,&l,&r); int ans=0; for (int d=17;d>=0;d--) { int tmp=b&(1<<d); if (tmp) { int ll=max(ans-x,0),rr=min(ans+(1<<d)-1-x,inf); if (!query(root[l-1],root[r],0,inf,ll,rr)) ans^=(1<<d); } else { ans^=(1<<d); int ll=max(ans-x,0),rr=min(ans+(1<<d)-x-1,inf); if (!query(root[l-1],root[r],0,inf,ll,rr)) ans^=(1<<d); } } printf("%d ",b^ans); } return 0; }