传送门:bzoj2819
题解
题中的Nim游戏其实就是看选中的这几堆石头每堆石头数量的异或和是否为0。
我们只需要维护每个点到根节点路径上的异或和就好了。
每次询问只要把两个节点到根节点路径异或和异或起来(抵消了LCA-ROOT一段)再异或一下LCA就好了。
对于修改,考虑只会影响到该节点为根的子树内的所有节点。直接dfs序建个线段树改一下。
被题面坑了,写了一个手写栈。
代码
#include<bits/stdc++.h>
using namespace std;
const int M=1e7+10;
const int N=5e5+10;
int n,m,T,f[N][19];
int Q[M],top,a[N],b[N],d[N],ans;
int mv[N<<2],orz[N<<2],bin[20],ori[N];
int head[N],to[N<<1],nxt[N<<1],tot;
int df[N],ot[N],in[N],cnt,as[N];
int opt;
inline int rd(){
char ch;int x=0,f=1;
while(!isdigit(ch=getchar())){
if(ch=='-') f=0;}
x=(ch^