[BZOJ2819]Nim-树状数组-dfs序
2017-08-24 01:15
323 查看
Nim
Description
著名游戏设计师vfleaking,最近迷上了Nim。普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取。谁不能取谁输。这个游戏是有必胜策略的。于是vfleaking决定写一个玩Nim游戏的平台来坑玩家。为了设计漂亮一点的初始局面,vfleaking用以下方式来找灵感:拿出很多石子,把它们聚成一堆一堆的,对每一堆编号1,2,3,4,…n,在堆与堆间连边,没有自环与重边,从任意堆到任意堆都只有唯一一条路径可到达。然后他不停地进行如下操作:
1.随机选两个堆v,u,询问若在v到u间的路径上的石子堆中玩Nim游戏,是否有必胜策略,如果有,vfleaking将会考虑将这些石子堆作为初始局面之一,用来坑玩家。
2.把堆v中的石子数变为k。
由于vfleaking太懒了,他懒得自己动手了。请写个程序帮帮他吧。
Input
第一行一个数n,表示有多少堆石子。接下来的一行,第i个数表示第i堆里有多少石子。
接下来n-1行,每行两个数v,u,代表v,u间有一条边直接相连。
接下来一个数q,代表操作的个数。
接下来q行,每行开始有一个字符:
如果是Q,那么后面有两个数v,u,询问若在v到u间的路径上的石子堆中玩Nim游戏,是否有必胜策略。
如果是C,那么后面有两个数v,k,代表把堆v中的石子数变为k。
对于100%的数据:
1≤N≤500000, 1≤Q≤500000, 0≤任何时候每堆石子的个数≤32767
其中有30%的数据:
石子堆组成了一条链,这3个点会导致你DFS时爆栈(也许你不用DFS?)。其它的数据DFS目测不会爆。
注意:石子数的范围是0到INT_MAX
Output
对于每个Q,输出一行Yes或No,代表对询问的回答。Sample Input
51 3 5 2 5
1 5
3 5
2 5
1 4
6
Q 1 2
Q 3 5
C 3 7
Q 1 2
Q 2 4
Q 5 3
Sample Output
YesNo
Yes
Yes
Yes
警告:本文作者因调试手工栈而神志不清,接下来可能会出现代码风格奇怪、语言逻辑混乱等特殊现象,特此告知。
要是没有这该死的手工栈啊啊啊啊啊啊啊啊啊啊
调了这么久全TM因为手写栈啊啊啊啊啊啊啊啊啊啊
(╯‵□′)╯︵┻━┻
思路:根据Nim游戏性质,先手存在必胜策略当且仅当所有石子数异或和不为0。
所以咱要维护的是异或值。
那么因为它只修改单点点权,这样影响的对象为其子树内的所有点,这在dfs序上正好为连续的一段。
于是考虑(用手工栈!!!!!)获取dfs序,然后运用差分,在一个点的dfs序起点处异或其值,终点处再异或其值以取消其值,即修改了子树内的值。
考虑回答询问。要查询路径上的异或和,就是对树状数组查询两个点dfs序上的起点,得到的值互相异或再异或上这两个点lca的值。
然后考虑修改,根据异或性质,只需像插入时一样再插入一次,即可消除其影响。
最后,lca咱用的是(用手工栈!!!!!!)写的树链剖分……
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; inline int read() { int x=0;char ch=getchar(); while(ch<'0' || '9'<ch)ch=getchar(); while('0'<=ch && ch<='9')x=x*10+(ch^48),ch=getchar(); return x; } const int N=500009; const int M=1000009; int n; int q ,cur ,st ,ed ,l,r; int w ,to[N<<1],nxt[N<<1],beg ,tot; int fa ,top ,siz ,son ,dep ,val ; int bit[M]; inline int lowbit(int x) { return x&(-x); } inline int query(int x) { int ret=0; while(x) { ret^=bit[x]; x-=lowbit(x); } return ret; } inline void insert(int a) { int x=st[a]; while(x<M) { bit[x]^=val[a]; x+=lowbit(x); } x=ed[a]; while(x<M) { bit[x]^=val[a]; x+=lowbit(x); } } inline void adde(int u,int v) { to[++tot]=v; nxt[tot]=beg[u]; beg[u]=tot; } inline void add(int u,int v) { adde(u,v);adde(v,u); } inline void pre() { memcpy(cur,beg,sizeof(beg)); q[r=1]=1; st[1]=l=1; fa[1]=0; dep[1]=1; while(r) { int u=q[r],v,flag=0; if(cur[u] && to[cur[u]]==fa[u]) { flag=1; cur[u]=nxt[cur[u]]; } else if(cur[u] && (v=to[cur[u]])!=fa[u]) { fa[v]=u; dep[v]=dep[u]+1; st[v]=++l; cur[u]=nxt[cur[u]]; q[++r]=v; flag=1; } if(!flag) { ed[u]=++l; r--; } } l=0; q[r=1]=1; siz[1]=1; while(l<r) { int u=q[++l]; for(int i=beg[u],v;i;i=nxt[i]) if((v=to[i])!=fa[u]) { q[++r]=v; siz[v]=1; } } for(int i=n;i;i--) siz[fa[q[i]]]+=siz[q[i]]; for(int i=1;i<=n;i++) if(!son[fa[i]] || siz[son[fa[i]]]<siz[i]) son[fa[i]]=i; top[1]=top[0]=1; for(int i=1;i<=n;i++) { if(son[fa[q[i]]]==q[i]) top[q[i]]=top[fa[q[i]]]; else top[q[i]]=q[i]; } } inline int lca(int a,int b) { while(top[a]!=top[b]) { if(dep[top[a]]<dep[top[b]]) swap(a,b); a=fa[top[a]]; } if(dep[a]<dep[b]) return a; return b; } int main() { n=read(); for(int i=1;i<=n;i++) val[i]=read(); for(int i=1;i<n;i++) add(read(),read()); pre(); for(int i=1;i<=n;i++) insert(i); int q=read(); char ch[4]; while(q--) { scanf("%s",ch); if(ch[0]=='Q') { int u=read(); int v=read(); if(query(st[u])^query(st[v])^val[lca(u,v)]) puts("Yes"); else puts("No"); } else { int u=read(); int v=read(); insert(u); val[u]=v; insert(u); } } return 0; }
相关文章推荐
- BZOJ 2819: Nim dfs序维护树状数组,倍增
- [BZOJ2819] Nim && dfs序 + 树状数组 + LCA
- 【手动开栈】【dfs序】【树状数组】【Tarjan】bzoj2819 Nim
- BZOJ 2819: Nim( nim + DFS序 + 树状数组 + LCA )
- BZOJ 1103 [POI 2007] dfs序+树状数组 解题报告
- 【BZOJ-3881】Divljak AC自动机fail树 + 树链剖分+ 树状数组 + DFS序
- [BZOJ 2819]NIM(dfs序维护树上xor值)
- 【BZOJ1103】[POI2007]大都市meg【树链剖分】【线段树】【或 树状数组 + dfs序】
- BZOJ 4765: 普通计算姬 [分块 树状数组 DFS序]
- [广义后缀自动机 set启发式合并 || dfs序 树状数组 离线] BZOJ 2780 [Spoj]8093 Sevenk Love Oimaster
- BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]
- BZOJ2819 Nim(DFS序)
- 【Tyvj2133&BZOJ1146】网络管理Network(树套树,DFS序,树状数组,主席树,树上差分)
- [dfs序 树状数组] BZOJ 1103 [POI2007]大都市meg
- bzoj 2434 (NOI2011)阿狸的打字机 【AC自动机】【树状数组】【DFS序】
- BZOJ 2434: [Noi2011]阿狸的打字机( AC自动机 + DFS序 + 树状数组 )
- BZOJ.2434.[NOI2011]阿狸的打字机(AC自动机 树状数组 DFS序)
- BZOJ 2434 阿狸的打字机 补全AC自动机 ( Trie图 ) fail树 树状数组 DFS序列
- [BZOJ - 2819] Nim 【树链剖分 / DFS序】
- BZOJ:2819 NIM(树链剖分||DFS序 &&NIM博弈)