题解:
比较简单的一道题
线段树+线性基
显然离线处理出位置
然后线段树updata的时候暴力合并线性基
nlogn^3
一个常数优化就是线性基已满就直接返回这个线性基
还有个优化是用快速找到第一个1的函数
代码:
#include <bits/stdc++.h> using namespace std; #define rint register ll #define IL inline #define me(x) memset(x,0,sizeof(x)) #define rep(i,h,t) for (rint i=h;i<=t;i++) #define dep(i,t,h) for (rint i=t;i>=h;i--) ll n,m,num; const ll N=12e4; char ss[1<<24],*A=ss,*B=ss; IL char gc() { return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++; } template<class T> void IL read(T &x) { rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48); while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f; } struct re{ ll a,b,c; }a[N]; ll cnt[N],sum[N]; vector<ll> ve; struct sgt{ #define mid ((h+t)/2) ll f[N*4][32]; IL void cr(ll *c,ll k) { dep(i,31,1) { if (!k) return; if (k&(1<<(i-1))) { if (!c[i]) { c[i]=k; return; } else k^=c[i]; } } } struct re2{ ll a[32]; re2 () { memset(a,0,sizeof(a)); } }; IL re2 hb(ll *x,ll *y) { ll cnt1=0,cnt2=0; rep(i,1,31) if (x[i]) cnt1++; rep(i,1,31) if (y[i]) cnt2++; re2 now; if(cnt1==31) { rep(i,1,31) now.a[i]=x[i]; return(now); } if (cnt2==31) { rep(i,1,31) now.a[i]=y[i]; return(now); } if (cnt1<cnt2) { rep(i,1,31) now.a[i]=y[i]; rep(i,1,31) if (x[i]) cr(now.a,x[i]); } else { rep(i,1,31) now.a[i]=x[i]; rep(i,1,31) if (y[i]) cr(now.a,y[i]); } return(now); } IL void updata(ll x) { re2 now=hb(f[x*2],f[x*2+1]); rep(i,1,31) f[x][i]=now.a[i]; } void query(ll x,ll h,ll t,ll h1,ll t1) { if (h1<=h&&t<=t1) { ve.push_back(x); return; } if (h1<=mid) query(x*2,h,mid,h1,t1); if (mid<t1) query(x*2+1,mid+1,t,h1,t1); } void change(ll x,ll h,ll t,ll pos,ll k) { if (h==t) { cr(f[x],k); return; } if (pos<=mid) change(x*2,h,mid,pos,k); else change(x*2+1,mid+1,t,pos,k); updata(x); } IL ll query2() { re2 now; for(ll i=0;i<ve.size();i++) now=hb(now.a,f[ve[i]]); ll ans=0; for(ll i=31;i>=1;i--) if (now.a[i]&&!(ans&(1<<(i-1)))) ans^=now.a[i]; return ans; } }S; ll main() { freopen("1.in","r",stdin); freopen("1.out","w",stdout); read(m); read(n); rep(i,1,m) { ll k,x,y; read(k); read(x); read(y); a[i].a=k; a[i].b=x; a[i].c=y; if (k==1) cnt[x]++; } rep(i,1,n) cnt[i]+=cnt[i-1]; num=cnt[n]; rep(i,1,m) { ll k=a[i].a,x=a[i].b,y=a[i].c; if (k==1) { sum[x]++; S.change(1,1,num,cnt[x-1]+sum[x],y); } else { ve.clear(); if (cnt[x-1]+1<=cnt[y]) { S.query(1,1,num,cnt[x-1]+1,cnt[y]); cout<<S.query2()<<endl; } else cout<<0<<endl; } } return 0; }