求问此题在线做法
查看原帖
求问此题在线做法
557510
AzureHair楼主2023/7/17 23:18

集训Day2讲了本题的在线做法,利用可持久化线段树和二维数点的知识来解决本题,但是好像空间过不了其实是自己菜,求问有人过了吗帮忙指点一下。

#include<bits/stdc++.h>
using namespace std;
int n,m,c[1000010],s[1000010],cnt1=0,pre[1000010],last[1000010],cnt=0,top[1000010];
map<int,int> mp;
struct node
{
	int l,r,v,L,R;
}t[32000010];
int build(int a,int b)
{
	int rt=++cnt;
	int mid=(a+b)>>1;
	t[rt].L=a;t[rt].R=b;
	if(a<b)
	{
		t[rt].l=build(a,mid);
		t[rt].r=build(mid+1,b);
	}
	return rt;
}
int update(int x,int k,int k1)
{
	int rt=++cnt;
	t[rt].l=t[x].l;t[rt].r=t[x].r;t[rt].v=t[x].v;t[rt].L=t[x].L;t[rt].R=t[x].R;
	int mid=(t[rt].L+t[rt].R)>>1;
	if(t[rt].L==t[rt].R)
	{
		t[rt].v^=k1;
		return rt;
	}
	if(t[rt].L<t[rt].R)
	{
		if(k<=mid)
		{
			t[rt].l=update(t[x].l,k,k1);
		}
		else
		{
			t[rt].r=update(t[x].r,k,k1);
		}
	}
	t[rt].v=(t[t[rt].l].v)^(t[t[rt].r].v);
	return rt;
}
int query(int x,int l,int r)
{
	if(l<=t[x].L&&r>=t[x].R)
	{
		return t[x].v;
	}
	int mid=(t[x].L+t[x].R)>>1;
	int ans=0;
	if(l<=mid)
	{
		ans=ans^query(t[x].l,l,r);
	}
	if(r>mid)
	{
		ans=ans^query(t[x].r,l,r);
	}
	return ans;
}
signed main()
{
	cin>>n;
	top[0]=1;
	for(int i=1;i<=n;i++)
	{
		cin>>c[i];
		if(!mp[c[i]])
		{
			mp[c[i]]=++cnt1;
		}
		pre[i]=last[mp[c[i]]];
		last[mp[c[i]]]=i;
		s[i]=s[i-1]^c[i];
	}
	cin>>m;
	build(0,n);
	for(int i=1;i<=n;i++)
	{
		top[i]=update(top[i-1],pre[i],c[i]);
	}
	for(int i=1;i<=m;i++)
	{
		int x,y;
		cin>>x>>y;
		cout<<(query(top[y],0,x-1)^query(top[x-1],0,x-1)^s[y]^s[x-1])<<endl;
	}
	return 0;
}
2023/7/17 23:18
加载中...