分析:
这个题,还是蛮有趣的。考虑,如果l,r区间内的所有数出现奇数次,那么[l-1,r]的抑或和等于所得抑或和。
之后怎么维护呢,主席树维护区间抑或和,记得将每个点附上一个ull级别的随机数,之后抑或的结果冲突的概率就几乎没有了。
lca什么的,随便求。
剩下的,考虑二分答案,如果左区间的全为奇数个,就往右走,反之往左走。
附上代码:
#include#include #include #include #include #include #include using namespace std;#define N 205005#define lson l,m,tr[rt].ls#define rson m+1,r,tr[rt].rs#define ll unsigned long long#define clear(rt) tr[rt].ls=tr[rt].rs=tr[rt].sum=0;struct node{ int ls,rs; ll sum;}tr[N*20];struct no{ int to,next;}e[N<<1];int dep[N],rot[N],fa[N],anc[N],siz[N],son[N],head[N],cnt,a[N],n,maxn,Q;ll val[N];void add(int x,int y){ e[++cnt].to=y; e[cnt].next=head[x]; head[x]=cnt;}void insert(int x,int v,ll c,int l,int r,int &rt){ rt=++cnt;clear(rt);tr[rt].sum=tr[x].sum^c; if(l==r)return;int m=(l+r)>>1; if(m>=v)tr[rt].rs=tr[x].rs,insert(tr[x].ls,v,c,lson); else tr[rt].ls=tr[x].ls,insert(tr[x].rs,v,c,rson);}void dfs1(int x,int from){ fa[x]=from,dep[x]=dep[from]+1,siz[x]=1; insert(rot[from],a[x],val[a[x]],1,maxn,rot[x]); for(int i=head[x];i!=-1;i=e[i].next) { int to1=e[i].to; if(to1!=from) { dfs1(to1,x); siz[x]+=siz[to1]; if(siz[to1]>siz[son[x]])son[x]=to1; } }}void dfs2(int x,int top){ anc[x]=top;if(son[x])dfs2(son[x],top); for(int i=head[x];i!=-1;i=e[i].next) { int to1=e[i].to; if(to1!=fa[x]&&to1!=son[x])dfs2(to1,to1); }}int get_lca(int x,int y){ while(anc[x]!=anc[y]) { if(dep[anc[x]] >1; if((tr[tr[x].ls].sum^tr[tr[y].ls].sum^tr[tr[lca].ls].sum^tr[tr[f].ls].sum)==(s[m]^s[l-1])) { l=m+1,x=tr[x].rs,y=tr[y].rs,lca=tr[lca].rs,f=tr[f].rs; }else { r=m,x=tr[x].ls,y=tr[y].ls,lca=tr[lca].ls,f=tr[f].ls; } } printf("%d\n",l); } } return 0;}