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

【样例输入】
5
1 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

Yes
No
Yes
Yes
Yes

Solution

据说会爆栈然而啥都没发生。

仔细阅读题目,其实就是一棵树,那么询问的本质就是在u和v的路径间做Nim游戏

直接树剖+线段树维护树上xor和判断是否为0就好

#include <bits/stdc++.h>

#define ll long long
#define inf 0x3f3f3f3f
#define il inline namespace io { #define in(a) a=read()
#define out(a) write(a)
#define outn(a) out(a),putchar('\n') #define I_int int
inline I_int read() {
I_int x = , f = ; char c = getchar() ;
while( c < '' || c > '' ) { if( c == '-' ) f = - ; c = getchar() ; }
while( c >= '' && c <= '' ) { x = x * + c - '' ; c = getchar() ; }
return x * f ;
}
char F[ ] ;
inline void write( I_int x ) {
if( x == ) { putchar( '' ) ; return ; }
I_int tmp = x > ? x : -x ;
if( x < ) putchar( '-' ) ;
int cnt = ;
while( tmp > ) {
F[ cnt ++ ] = tmp % + '' ;
tmp /= ;
}
while( cnt > ) putchar( F[ -- cnt ] ) ;
}
#undef I_int }
using namespace io ; using namespace std ; #define N 500010 int dep[N] , top[N] , id[N] , siz[N] , fa[N] , w[N] ;
int n = read() , a[N] , tot = ;
int cnt , head[N] ;
struct edge {
int to , nxt ;
} e[N<<] ; void ins(int u , int v) {
e[ ++ cnt ] = (edge) {v , head[u]} ;
head[u] = cnt ;
} void dfs1(int u) {
siz[u] = ;
for(int i = head[u] ; i ; i = e[i].nxt) {
if(e[i].to == fa[u]) continue ;
fa[e[i].to] = u ;
dep[e[i].to] = dep[u] + ;
dfs1(e[i].to) ;
siz[u] += siz[e[i].to] ;
}
} void dfs2(int u , int topf) {
top[u] = topf ;
id[u] = ++ tot ;
w[tot] = a[u] ;
int k = ;
for(int i = head[u] ; i ; i = e[i].nxt) {
if(e[i].to == fa[u]) continue ;
if(siz[e[i].to] > siz[k]) k = e[i].to ;
}
if(!k) return ;
dfs2(k , topf) ;
for(int i = head[u] ; i ; i = e[i].nxt) {
if(e[i].to == fa[u] || k == e[i].to) continue ;
dfs2(e[i].to , e[i].to) ;
}
} // seg-tree
struct tree {
int l , r , sum ;
} t[N << ]; #define lc (rt << 1)
#define rc (rt << 1 | 1) void pushup(int rt) { t[rt].sum = t[lc].sum ^ t[rc].sum ; } void build(int l , int r , int rt) {
t[rt].l = l ; t[rt].r = r ; int mid = (l + r) >> ;
if(l == r) { t[rt].sum = w[l] ; return ; }
build(l , mid , lc) ; build(mid + , r , rc) ; pushup(rt) ;
} #define l t[rt].l
#define r t[rt].r
#define mid ((l + r) >> 1) void upd(int L , int c , int rt) {
if(l == r) {t[rt].sum = c ; return ;}
if(L <= mid) upd(L , c , lc) ;
else upd(L , c , rc) ;
pushup(rt) ;
} int query(int L , int R , int rt) {
if(L <= l && r <= R) return t[rt].sum ; int ans = ;
if(L <= mid) ans ^= query(L , R , lc) ; if(R > mid) ans ^= query(L , R , rc) ;
return ans ;
} #undef lc
#undef rc
#undef l
#undef r
#undef mid
// seg-tree end void query(int x , int y) {
int ans = ;
while(top[x] != top[y]) {
if(dep[top[x]] < dep[top[y]]) swap(x , y) ;
ans ^= query(id[top[x]] , id[x] , ) ;
x = fa[top[x]] ;
}
if(dep[x] > dep[y]) swap(x , y) ;
ans ^= query(id[x] , id[y] , ) ;
if(ans) puts("Yes") ;
else puts("No") ;
} int main() {
for(int i = ; i <= n ; i ++) a[i] = read() ;
for(int i = ; i < n ; i ++) {
int u = read() , v = read() ;
ins(u , v) , ins(v , u) ;
}
dfs1() ; dfs2(,) ; build(,n,) ;
int m = read() ;
while(m--) {
char ch[] ; scanf("%s" , ch);
int x = read() , y = read() ;
if(ch[] == 'Q') query(x , y) ;
else upd(id[x] , y , ) ;
}
}

BZOJ2819: Nim 树链剖分的更多相关文章

  1. BZOJ 2819 Nim 树链剖分+树状数组

    这题真没什么意思. 不过就是将普通的求Min,Max,求和等东西换成Xor,偏偏Xor还有很多性质. 算是刷道水题吧. #include<iostream> #include<cst ...

  2. [BZOJ - 2819] Nim 【树链剖分 / DFS序】

    题目链接: BZOJ - 2819 题目分析 我们知道,单纯的 Nim 的必胜状态是,各堆石子的数量异或和不为 0 .那么这道题其实就是要求求出树上的两点之间的路径的异或和.要求支持单点修改. 方法一 ...

  3. BZOJ2819Nim——树链剖分+线段树+Nim游戏

    题目描述 著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取.谁不能取谁输.这个游戏是有必胜策略 ...

  4. 【BZOJ】2819: Nim(树链剖分 / lca+dfs序+树状数组)

    题目 传送门:QWQ 分析 先敲了个树链剖分,发现无法AC(其实是自己弱,懒得debug.手写栈) 然后去学了学正解 核心挺好理解的,$ query(a) $是$ a $到根的异或和. 答案就是$ l ...

  5. 西安邀请赛-E(树链剖分+线段树)

    题目链接:https://nanti.jisuanke.com/t/39272 题意:给一棵树,n个结点,树根为1,n-1条边,每个结点有一个权值.进行3种操作: 1 s t:把1和s之间的最短路径上 ...

  6. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

  7. BZOJ 1984: 月下“毛景树” [树链剖分 边权]

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1728  Solved: 531[Submit][Status][Discu ...

  8. codevs 1228 苹果树 树链剖分讲解

    题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...

  9. 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)

    题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...

随机推荐

  1. mac chrome 驱动配置

    将解压后的chromedriver移动到/usr/local/bin目录下

  2. 【HTML5】实例练习

    1.许多时髦的网站都提供视频.如果在网页上展示视频? <!DOCTYPE HTML> <html> <body> <video width="320 ...

  3. python基础班-淘宝-目录.txt

    卷 TOSHIBA EXT 的文件夹 PATH 列表卷序列号为 AE86-8E8DF:.│ python基础班-淘宝-目录.txt│ ├─1-1 Linux基础│ ├─01-课程简介│ │ 01-课程 ...

  4. (4.15)存储DAS,NAS,SAN在数据库存储上的应用

    关键词:存储,硬盘接口类型,磁盘类型,网络类型,DAS,DNS,SAN 转自:http://blog.51cto.com/qianzhang/1254617 一. 硬盘接口类型 1. 并行接口还是串行 ...

  5. [vue]组件的创建(componet)和销毁(keep-alive缓存)和父子dom同步nextTick

    思路: 1. 组件的好处,重用性 2. 组件对的slot用法 3. 子如何调用父的数据 4. 子如何触发父的方法执行 5. 父如何触发子的方法执行 6. 如何创建组件和销毁自建--如何缓存避免每次切换 ...

  6. [django]django的orm查询

    实体 实体 出版社 category 作者 tag 书 文章 先学习一下基础的增删查改 django orm增删改查: https://www.cnblogs.com/iiiiiher/article ...

  7. ZOJ:2833 Friendship(并查集+哈希)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2833 A friend is like a flower, a rose ...

  8. C#--virtual,abstract,override,new,sealed修饰符学习

    1.参考博客  http://www.cnblogs.com/oneword/archive/2009/07/02/1515279.html http://www.cnblogs.com/mygood ...

  9. redis和memcached相关

    应该选择哪一种缓存机制 redis相较于memcached更加年轻,功能更加强大. 对小型静态数据进行缓存处理,最具代表性的例子就是HTML代码片段.使用memcached所消耗内存更少. 其他情况下 ...

  10. 十图详解tensorflow数据读取机制

    在学习tensorflow的过程中,有很多小伙伴反映读取数据这一块很难理解.确实这一块官方的教程比较简略,网上也找不到什么合适的学习材料.今天这篇文章就以图片的形式,用最简单的语言,为大家详细解释一下 ...