n居然是10w左右你敢信。。。连爆10+发OJ才发现。
首先给每一个子树一个sg值;考虑当前点所在子树的sg,枚举第一次删哪一个点,那么剩下一些子树,这些子树的xor就是这个后继的值,然后求mex即可。
考虑用线段树合并来维护。用线段树维护某一个要被删除的点在当前点的后继的值,那么更新就相当于全部抑或一个值,打标记维护即可。
查询就贪心向左走即可。
AC代码如下:
#include<bits/stdc++.h>
#define N 200005
#define M 4000005
#define clr(x,y) memset(x,0,sizeof(int)*(y+1))
using namespace std;
int n,m,tot,trtot,bin[25],fst[N],pnt[N],nxt[N],fa[N],sg[N],rt[N],ls[M],rs[M],sz[M],tg[M];
bool vis[N];
void add(int x,int y){
pnt[++tot]=y; nxt[tot]=fst[x]; fst[x]=tot;
}
void pushdn(int x,int k){
if (tg[x]){
if (tg[x]&bin[k-1]) swap(ls[x],rs[x]);