Meaning of the questions: to give you an array with two operation, Interval xor a value, a number of species is the result of the query interval xor
A practice:
for a given interval, we can find several types of results by means of solving linear base, and now it just put online a tree maintenance interval linear base.
With a segment tree maintenance intervals to merge
#include <bits/stdc++.h> using namespace std; const int maxn = 1e5; struct node { int bas[30],lazy,st; void init() { memset(bas,0,sizeof(bas)); lazy = 0;st = 0; } int Count() { int ans = 0; for(int i = 0;i<=29;i++) { if(bas[i]) ans++; } return ans; } void add(int x) { for(int i = 29;i>=0;i--) { if((x>>i)&1){ if(bas[i])x^=bas[i]; else { bas[i] = x; break; } } } } node operator + (const node &a) const{ node ans; ans.init(); for(int i = 0;i<=29;i++) { ans.add(bas[i]); ans.add(a.bas[i]); } ans.add(st^a.st); ans.st = a.st; return ans; } }tr[8*maxn],ans; int n,q; void pushdown(int st) { if(tr[st].lazy) { tr[st<<1].lazy ^= tr[st].lazy; tr[st<<1].st ^= tr[st].lazy; tr[st<<1|1].lazy ^= tr[st].lazy; tr[st<<1|1].st ^= tr[st].lazy; tr[st].lazy = 0; } } void build(int l,int r,int st) { tr[st].init(); if(l == r) { scanf("%d",&tr[st].st); return ; } int mid = (l+r)>>1; build(l,mid,st<<1); build(mid+1,r,st<<1|1); tr[st] = tr[st<<1] + tr[st<<1|1]; } void update(int l,int r,int st,int L,int R,int d) { if(l>=L && r<=R) { tr[st].lazy ^= d; tr[st].st ^= d; return ; } pushdown(st); int mid = (l+r) >>1; if(L<=mid) update(l,mid,st<<1,L,R,d); if(R> mid) update(mid+1,r,st<<1|1,L,R,d); tr[st] = tr[st<<1] + tr[st<<1|1]; } void Query(int l,int r,int st,int L,int R) { if(l >= L && r <= R) { ans = ans + tr[st]; return ; } pushdown(st); int mid = (l+r) >>1; if(L<=mid) Query(l,mid,st<<1,L,R); if(R>mid) Query(mid+1,r,st<<1|1,L,R); tr[st] = tr[st<<1] + tr[st<<1|1]; } int main() { int op,l,r,d; scanf("%d %d",&n,&q); build(1,n,1); while(q--) { scanf("%d %d %d",&op,&l,&r); if(op == 1) { scanf("%d",&d); update(1,n,1,l,r,d); } else { ans.init(); Query(1,n,1,l,r); printf("%d\n",1<<ans.Count()); } } return 0; }
Practice two:
The original sequence of a differential, such that b [i] = a [i] ^ a [i + 1], then al, al + 1, al + 2, a XOR and ar may be constituted, in al, bl, bl + 1, bl + 2, br-1 certainly also be constructed, so the two are equivalent.
A sequence for updating interval [l, r] in fact only the sequence b and bl-1 br affected, since the number of intermediate pairwise so cancel out.
So now it becomes a single point of update interval linear segment tree maintenance group, and then use a tree-like array of positions to be modified to maintain the value of l, which uses a differential, where the effect is required A [l] values.
#include <bits/stdc++.h> #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 using namespace std; const int mx = 2e5 + 10; int n,m,a[mx],b[mx]; int pre[mx],mv; struct node{ int gao[31]; void add(int x){ for(int i=29;i>=0;i--){ if(x&(1<<i)){ if(!gao[i]){ gao[i] = x; break; }else x ^= gao[i]; } } } node operator + (node A)const { node ret = A; for(int i=29;i>=0;i--) if(gao[i]) ret.add(gao[i]); return ret; } }s[mx<<2]; void add(int x,int v){ while(x<=n){ pre[x] ^= v; x += x&(-x); } } int getpre(int x){ int ans = 0; while(x){ ans ^= pre[x]; x -= x&(-x); } return ans; } void build(int l,int r,int rt) { if(l==r){ b[l] = a[l]^a[l+1]; for(int i=29;i>=0;i--) if((1<<i)&b[l]){ s[rt].gao[i] = b[l]; break; } return ; } int mid = (l+r)>>1; build(lson);build(rson); s[rt] = s[rt<<1] + s[rt<<1|1]; } void update(int l,int r,int rt,int M) { if(l==r){ b[l] ^= mv; memset(s[rt].gao,0,sizeof(s[rt].gao)); for(int i=29;i>=0;i--) if((1<<i)&b[l]){ s[rt].gao[i] = b[l]; break; } return ; } int mid = (l+r)>>1; if(M<=mid) update(lson,M); else update(rson,M); s[rt] = s[rt<<1] + s[rt<<1|1]; } node query(int l,int r,int rt,int L,int R) { if(L<=l&&r<=R) return s[rt]; int mid = (l+r)>>1; if(L<=mid&&R>mid) return query(lson,L,R) + query(rson,L,R); if(L<=mid) return query(lson,L,R); return query(rson,L,R); } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",a+i); if(n>1) build(1,n-1,1); int o,l,r; while(m--){ scanf("%d%d%d",&o,&l,&r); if(o==1){ scanf("%d",&mv); add(l,mv);add(r+1,mv); if(l>1) update(1,n-1,1,l-1); if(r<n) update(1,n-1,1,r); }else{ int v = a[l]^getpre(l); if(n==1||l==r) printf("%d\n",v?2:1); else{ node ans = query(1,n-1,1,l,r-1); ans.add(v); int ret = 0; for(int i=29;i>=0;i--) if(ans.gao[i]) ret++; printf("%d\n",1<<ret); } } } return 0; }