题解 CF703D 【Mishka and Interesting sum】
发现题解没有在线算法,那我就来写一篇
首先,答案是区间不重复的数的异或和
我们将每个数升到二维,第一位是位置,第二维记录一个
区间为奇数的数的异或和用一个异或前缀和就行,因为出现偶数次数的数都相互抵消掉了
代码
#include<bits/stdc++.h>
using namespace std;
namespace OI{
#define rg register
template <typename T>
inline void read(T &x){
x=0;
static char ch;ch=getchar();
static int f; f=0;
while(!isdigit(ch)) f|=(ch=='-'),ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
x=f?-x:x;
}
const int N=300005;
int sum[N];
int a[N],n,m;
int xorsum[N<<5];
int rt[N],son[N<<5][2],cnt;
#define ls son[p][0]
#define rs son[p][1]
#define pls son[pre][0]
#define prs son[pre][1]
int head[1000004],mod=1000003,tot,nxt[N],edge[N],pre[N],second[N];
inline void add(int x,int st){
for(int i=head[x%mod];i;i=nxt[i]){
if(edge[i]==x) return (void) (pre[i]=st);
}
nxt[++tot]=head[x%mod];
head[x%mod]=tot;
edge[tot]=x;
pre[tot]=st;
}
inline int find(int x){
for(int i=head[x%mod];i;i=nxt[i]){
if(edge[i]==x) return pre[i];
}
return false;
}
inline bool check(int p){
int len=sqrt(p);
for(int i=2;i<=len;++i) if(!(p%i)) return false;
return true;
}
int insert(int l,int r,int to,int d,int pre){
int p=++cnt;
ls=pls;rs=prs;
xorsum[p]=xorsum[pre]^d;
if(l==r) return p;
int mid=(l+r)>>1;
if(to<=mid) ls=insert(l,mid,to,d,pls);
else rs=insert(mid+1,r,to,d,prs);
return p;
}
int ask(int l,int r,int L,int R,int pre,int p){
if(l==L&&r==R) return xorsum[p]^xorsum[pre];
int mid=(l+r)>>1;
if(L>mid) return ask(mid+1,r,L,R,prs,rs);
if(R<=mid) return ask(l,mid,L,R,pls,ls);
return ask(l,mid,L,mid,pls,ls)^ask(mid+1,r,mid+1,R,prs,rs);
}
inline void main(){
// freopen("xor.in","r",stdin);
// freopen("xor.out","w",stdout);
read(n);
for(int i=1;i<=n;++i){
read(a[i]);
second[i]=find(a[i]);
add(a[i],i);
rt[i]=insert(0,n,second[i],a[i],rt[i-1]);
sum[i]=sum[i-1]^a[i];
}
read(m);
int l,r;
for(int i=1;i<=m;++i){
read(l),read(r);
printf("%d\n",ask(0,n,0,l-1,rt[l-1],rt[r])^sum[l-1]^sum[r]);
}
}
}
signed main(){ OI::main(); return 0;}