comet oj #3 D 区间维护异或后的线性基
这不是原题吗...
具体做法参考codefores 587 E
不过这题卡常...
写题解纯粹是为了记录一下快读...
#include <bits/stdc++.h> #pragma GCC optimize("Ofast") #define rep(ii,a,b) for(register int ii=a;ii<=b;++ii) #define per(ii,a,b) for(register int ii=b;ii>=a;--ii) using namespace std; const int maxn=5e4+10,maxm=2e5+10; int casn,n,m,k,val[maxn],curpos = 0, iseof; struct bass{ int flag,val; int d[33]; inline void init(){val=flag=0;memset(d,0,sizeof d);} inline void insert(ll x){ for(register int i=30;x&&i>=0;--i) if(x&(1ll<<i)){ if(!d[i]) {d[i]=x;return;} else x^=d[i]; } } inline int query(int x){ register int ans=x; per(i,0,30){ if((ans^d[i])>ans) { ans^=d[i]; } } return ans; } inline void update(int x){val^=x;flag^=x;} }; namespace segtree{ #define nd node[now] #define ndl node[now<<1] #define ndr node[now<<1|1] inline bass marge(bass &a,bass b) { bass ans;ans.init(); per(i,0,30) ans.insert(a.d[i]),ans.insert(b.d[i]); ans.insert(a.val^b.val); ans.val=a.val; return ans; } bass node[maxn<<2|3]; inline void down(int now){ if(nd.flag){ ndl.update(nd.flag);ndr.update(nd.flag); nd.flag=0; } } void maketree(int s,int t,int now=1){ nd.init(); if(s==t) {nd.val=val[s];return ;} maketree(s,(s+t)/2,now<<1); maketree((s+t)/2+1,t,now<<1|1); nd=marge(ndl,ndr); } void update(int s,int t,int x,int l,int r,int now=1){ if(s<=l&&t>=r) {nd.update(x);return;} down(now);int mid=(l+r)/2; if(s<=mid) update(s,t,x,l,mid,now<<1); if(t>mid) update(s,t,x,mid+1,r,now<<1|1); nd=marge(ndl,ndr); } bass ans; void query(int s,int t,int l,int r,int now=1){ if(s<=l&&t>=r) { ans=marge(ans,nd); return ; } down(now);int mid=(l+r)/2; if(s<=mid) query(s,t,l,mid,now<<1); if(t>mid) query(s,t,mid+1,r,now<<1|1); } } inline void write(int x) {if(x>9) write(x / 10);putchar(x % 10 + '0');} char buf[100 * 1024 * 1024 + 5]; int nxint() { if (iseof) return 0; register int ret = 0,flg = 0; while (!('0' <= buf[curpos] && buf[curpos] <= '9')) { if (buf[curpos] == 0) { if (fgets(buf, 16 * 1024 * 1024, stdin) == NULL) iseof = true; curpos = 0; continue; } curpos++; } if (curpos && buf[curpos - 1] == '-') flg = -1; else flg = 1; while ('0' <= buf[curpos] && buf[curpos] <= '9') { ret = ret * 10 + (buf[curpos] - '0'); curpos++; } return ret * flg; } int main() { n=nxint(),m=nxint(); register int a,b,c,d; rep(i,1,n) val[i]=nxint(); segtree::maketree(1,n); rep(i,1,m){ a=nxint();b=nxint();c=nxint();d=nxint(); if(a==1)segtree::update(b,c,d,1,n); else { segtree::ans.init(); segtree::query(b,c,1,n); write(segtree::ans.query(d)); putchar('\n'); } }