数据结构好题3.1
本题使用动态开点线段树目的只是防止空间裂开
本题要求维护一个支持①区间求和②区间异或 的数据结构
这个题的数据规模有个很奇怪的地方,ai范围不大
一眼线段树,但区间异或显然不具备区间可加性。一般面对这种情况我们会转为区间求和的问题解决,而异或唯一的转化方法就是转化为二进制。联系数据规模我们会发现最多20位二进制,所以我们可以用线段树分别维护总共20位的状态,显然对区间异或可以转为对区间某一位取反的问题。具体不细说了,想到这里基本就透彻了,细节挺多的
#include<bits/stdc++.h> using namespace std; #define re register #define fo1(l,r) for(re int i=l;i<=r;++i) #define fo2(l,r) for(re int j=l;j<=r;++j) #define fo3(l,r) for(re int k=l;k<=r;++k) #define fo4(l,r) for(re int tt=l;tt<=r;++tt) #define fo(l) for(re int i=h[l],go;i;i=x[i].last) #define inf 0x3f3f3f3f #define INF 0x7fffffffffffffff #define LL long long #define itn int inline int read() { int x=0,f=1;char ch=getchar(); while(!isdigit(ch)) { if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)) { x=(x<<3)+(x<<1)+ch-48; ch=getchar(); } return x*f; } const int N=1e5+10; int a[N]; struct segmenttree { LL sum[20]; bool rev[20]; #define sum(x,y) tree[x].sum[y] #define rev(x,y) tree[x].rev[y] }tree[N<<1]; int cnt=1,ls[N<<1],rs[N<<1]; inline int yls(int p){return ls[p]?ls[p]:ls[p]=++cnt;}; inline int yrs(int p){return rs[p]?rs[p]:rs[p]=++cnt;}; #define l(x) yls(x) #define r(x) yrs(x) inline void ysp(int p,itn bh,int l,itn r) { if(rev(p,bh)) { int mid=(l+r)>>1; sum(l(p),bh)=mid-l+1-sum(l(p),bh); sum(r(p),bh)=r-mid-sum(r(p),bh); rev(l(p),bh)^=1; rev(r(p),bh)^=1; rev(p,bh)=0; } return; } inline void build(int p,int bh,int l,int r) { rev(p,bh)=0; if(l==r) { if((a[l]>>bh)&1) sum(p,bh)=1; else sum(p,bh)=0; return; } int mid=(l+r)>>1; build(l(p),bh,l,mid); build(r(p),bh,mid+1,r); sum(p,bh)=sum(l(p),bh)+sum(r(p),bh); return; } inline LL yask(itn p,int bh,int l,int r,int ll,int rr) { if(ll<=l && r<=rr) { return sum(p,bh); } ysp(p,bh,l,r); int mid=(l+r)>>1;LL S=0; if(ll<=mid) { S+=yask(l(p),bh,l,mid,ll,rr); } if(rr>mid) { S+=yask(r(p),bh,mid+1,r,ll,rr); } return S; } inline void yadd(int p,itn bh,int l,int r,int ll,int rr) { if(ll<=l && r<=rr) { sum(p,bh)=r-l+1-sum(p,bh); rev(p,bh)^=1; return; } ysp(p,bh,l,r); itn mid=(l+r)>>1; if(ll<=mid) { yadd(l(p),bh,l,mid,ll,rr); } if(rr>mid) { yadd(r(p),bh,mid+1,r,ll,rr); } sum(p,bh)=sum(l(p),bh)+sum(r(p),bh); return; } int main() { int n=read(); fo1(1,n) { a[i]=read(); } fo1(0,19) build(1,i,1,n); int m=read(); fo1(1,m) { int ty=read(); if(ty==1) { int l=read(),r=read(); LL ans,ANS=0; fo2(0,19) { ans=yask(1,j,1,n,l,r); ans*=(1ll<<j); ANS+=ans; } printf("%lld\n",ANS); } else { int l=read(),r=read(),x=read(); fo2(0,19) { if((x>>j)&1) yadd(1,j,1,n,l,r); } } } return 0; }

浙公网安备 33010602011771号