萌新求助线段树分治
查看原帖
萌新求助线段树分治
256970
xie_lzh楼主2022/7/29 20:30

能过样例,也只能过样例(

#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;
}
2022/7/29 20:30
加载中...