集训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;
}