能过样例,也只能过样例(
#include<bits/stdc++.h>
using namespace std;
#define int long long
int read()
{
int r=0,f=1;
char c=getchar();
while(!isdigit(c))
{
if(c=='-') f=0;
c=getchar();
}
while(isdigit(c))
{
r=(r<<1)+(r<<3)+c-48;
c=getchar();
}
return f?r:-r;
}
const int N=1e6+5;
int ch[N*50][2],siz[N*50],tot;
void insert(int &x,int pre,int val)
{
x=++tot; int u=x;
for(int i=18;i>=0;i--)
{
bool k=(val>>i)&1;
ch[u][(k^1)]=ch[pre][(k^1)];
ch[u][k]=++tot;
u=ch[u][k]; pre=ch[pre][k];
siz[u]=siz[pre]+1;
}
}
int query(int l,int r,int w)
{
int res=0;
for(int i=18;i>=0;i--)
{
bool d=w&(1<<i);
if(siz[ch[r][d^1]]-siz[ch[l][d^1]]>0)
l=ch[l][d^1],r=ch[r][d^1],res+=(1<<i);
else l=ch[l][d],r=ch[r][d];
}
return res;
}
int n,m,rt[N],cnt1,cnt2,ans[N];
struct node
{
int tim,id,val;
}pos[N],q1[N],q2[N];
struct edge
{
int l,r,L,R,w;
}q[N];
vector<int> v[N<<2];
int ls(int x){return x<<1;}
int rs(int x){return x<<1|1;}
void update(int p,int l,int r,int L,int R,int id)
{
if(L>R)return;
if(L<=l&&r<=R)
{
v[p].push_back(id);
return ;
}
int mid=(l+r)>>1;
if(L<=mid) update(ls(p),l,mid,L,R,id);
if(R>mid) update(rs(p),mid+1,r,L,R,id);
}
bool cmp(node x,node y)
{
return x.id<y.id;
}
int stk[N];
void calc(int p,int L,int R)
{
int top=tot=0;
for(int i=L;i<=R;i++)
{
stk[++top]=pos[i].id;
insert(rt[top],rt[top-1],pos[i].val);
}
for(auto i:v[p])
{
int l=upper_bound(stk+1,stk+1+top,q[i].l-1)-stk-1;
int r=upper_bound(stk+1,stk+1+top,q[i].r)-stk-1;
ans[i]=max(ans[i],query(rt[l],rt[r],q[i].w));
}
}
void devide(int p,int l,int r,int L,int R)
{
if(L>R) return ;
calc(p,L,R);
if(l==r) return ;
int sc1=0,sc2=0,mid=(l+r)>>1;
for(int i=L;i<=R;i++)
{
if(pos[i].tim<=mid) q1[++sc1]=pos[i];
else q2[++sc2]=pos[i];
}
for(int i=1;i<=sc1;i++) pos[L+i-1]=q1[i];
for(int i=1;i<=sc2;i++) pos[sc1+L+i-1]=q2[i];
devide(ls(p),l,mid,L,L+sc1-1);
devide(rs(p),mid+1,r,L+sc1,R);
}
signed main()
{
n=read(); m=read();
for(int i=1;i<=n;i++)
insert(rt[i],rt[i-1],read());
for(int opt,x,y,w,t,i=1;i<=m;i++)
{
opt=read(); x=read(); y=read();
if(opt==0) pos[++cnt1]=(node){cnt1,x,y};
else
{
w=read(); t=read();
ans[++cnt2]=query(rt[x-1],rt[y],x);
q[cnt2]=(edge){x,y,max(cnt1-t+1,1ll),cnt1,w};
}
}
for(int i=1;i<=cnt2;i++)
update(1,1,cnt1,q[i].L,q[i].R,i);
sort(pos+1,pos+1+cnt1,cmp);
devide(1,1,cnt1,1,cnt1);
for(int i=1;i<=cnt2;i++)
cout<<ans[i]<<endl;
}