【BZOJ2819】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

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

题解:一个常识结论:Nim游戏先手必胜当且仅当所有堆的异或和不为0,否则先手必输

然后用树状数组+倍增LCA维护DFS序的异或和就行了(当然,如果你维护的是入栈出栈序,可以不用倍增LCA)

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=500010;
int n,m,cnt;
int to[maxn<<1],next[maxn<<1],head[maxn],fa[maxn][20],dep[maxn],s[maxn],p[maxn],q[maxn],v[maxn];
char str[10];
int rd()
{int ret=0,f=1;   char gc=getchar();while(gc<'0'||gc>'9')  {if(gc=='-')f=-f;  gc=getchar();}while(gc>='0'&&gc<='9')  ret=ret*10+gc-'0',gc=getchar();return ret*f;
}
void add(int a,int b)
{to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
}
void dfs(int x)
{p[x]=++p[0];for(int i=head[x];i!=-1;i=next[i])if(to[i]!=fa[x][0])fa[to[i]][0]=x,dep[to[i]]=dep[x]+1,dfs(to[i]);q[x]=p[0];
}
void updata(int x,int val)
{if(!x) return ;for(int i=x;i<=n;i+=i&-i)    s[i]^=val;
}
int query(int x)
{int i,ret=0;for(i=x;i;i-=i&-i)  ret^=s[i];return ret;
}
int main()
{scanf("%d",&n);int i,j,a,b,c,d;memset(head,-1,sizeof(head));for(i=1;i<=n;i++) v[i]=rd();for(i=1;i<n;i++)   a=rd(),b=rd(),add(a,b),add(b,a);dep[1]=1,dfs(1);for(i=1;i<=n;i++) updata(p[i],v[i]),updata(q[i]+1,v[i]);for(j=1;(1<<j)<=n;j++)for(i=1;i<=n;i++)  fa[i][j]=fa[fa[i][j-1]][j-1];m=rd();for(i=1;i<=m;i++){scanf("%s",str),a=rd(),b=rd();if(str[0]=='Q'){c=a,d=b;if(dep[a]<dep[b]) swap(a,b);for(j=19;j>=0;j--)   if(dep[fa[a][j]]>=dep[b])   a=fa[a][j];if(a!=b){  for(j=19;j>=0;j--) if(fa[a][j]!=fa[b][j]) a=fa[a][j],b=fa[b][j];a=fa[a][0];}if(query(p[c])^query(p[d])^v[a])   printf("Yes\n");else  printf("No\n");}if(str[0]=='C'){updata(p[a],v[a]),updata(q[a]+1,v[a]);updata(p[a],b),updata(q[a]+1,b);v[a]=b;}}return 0;
}

转载于:https://www.cnblogs.com/CQzhangyu/p/7044261.html

【BZOJ2819】Nim 树状数组+LCA相关推荐

  1. [虚树][树状数组][lca] Jzoj P5908 开荒

    Description 题目背景: 尊者神高达作为一个萌新,在升级路上死亡无数次后被一只大黄叽带回了师门.他加入师门后发现有无穷无尽的师兄弟姐妹,这几天新副本开了,尊者神高达的师门作为一个 pve师门 ...

  2. jzoj4050-寻宝游戏【二分,树状数组,LCA】

    正题 题目链接:https://jzoj.net/senior/#contest/show/3017/1 题目大意 nnn个点的一棵树,mmm次操作,修改一个地方的宝藏. 每次操作后求拿完所以宝藏并回 ...

  3. 【HDU - 6203】ping ping ping(lca+贪心思想,对lca排序,树状数组差分)

    题干: 给出一个n+1个点的树,以及p个点对,需要断开一些点,使得这p个点对路径不连通.输出应该断开的最少点数. 解题报告: 从那p个点对入手的话:首先考虑只有一对点的话,肯定是这条路径上的随便一个点 ...

  4. 「模拟赛20180306」回忆树 memory LCA+KMP+AC自动机+树状数组

    题目描述 回忆树是一棵树,树边上有小写字母. 一次回忆是这样的:你想起过往,触及心底--唔,不对,我们要说题目. 这题中我们认为回忆是这样的:给定 \(2\) 个点 \(u,v\) (\(u\) 可能 ...

  5. Codeforces Gym 101142 G Gangsters in Central City (lca+dfs序+树状数组+set)

    题意: 树的根节点为水源,编号为 1 .给定编号为 2, 3, 4, -, n 的点的父节点.已知只有叶子节点都是房子. 有 q 个操作,每个操作可以是下列两者之一: + v ,表示编号为 v 的房子 ...

  6. Housewife Wind POJ - 2763 倍增LCA+树状数组 或 树链剖分+线段树

    题目 链接:http://poj.org/problem?id=2763 Language:Default Housewife Wind Time Limit: 4000MS   Memory Lim ...

  7. HDU 6203 ping ping ping (在线倍增lca+DFS序+树状数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6203 #include<bits/stdc++.h> using namespace st ...

  8. HDU 6203 2017沈阳网络赛 LCA,DFS+树状数组

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6203 题意:n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V ...

  9. hdu 5465 Clarke and puzzle (二维树状数组+nim博弈)

    解析: 利用二维树状数组来区间询问异或和,以及单点更新,然后利用nim博弈的结论判断胜负. mymy codecode #include <cstdio> #include <cst ...

最新文章

  1. python的数学模块是什么_Python的数学模块Think Python
  2. python gui打包exe pyinstaller打包运行失败 Failed to execute script pyi_rth_multiprocessing
  3. 多线程别怕,有锁就安全;(解决线程安全问题)
  4. eclipse打开当前文件所在文件夹
  5. webService学习3:客户端生成webservice代码
  6. 华为确认与三家EDA公司停止合作;开源安卓恶意软件窃取用户隐私信息;三星高通回应7纳米EUV工艺问题……...
  7. (82)介绍AXI4-Stream总线
  8. 【精华】Asp优化之缓存技术
  9. linux下搭建博客day4注册git账号
  10. php 低级语句,低级语言是什么?
  11. windows下JDK环境配置与Android SDK环境配置
  12. JS与Jquery学习笔记(二)
  13. OneNote 2016代码编写插件 安装
  14. cocos2dx检测及预防外挂加速
  15. 成都市二手房行情分析
  16. 【组队学习】【33期】LeetCode 刷题
  17. uniapp-小程序点击底部导航跳转并刷新页面
  18. 找不到匹配的host key算法
  19. ②计算机病毒实验实验报告
  20. 傅里叶特征学习高频:Fourier Features Let Networks Learn High Frequency Functions in Low Dimensional Domains

热门文章

  1. BugkuCTF-Misc:爆照(08067CTF)
  2. CVS有关no such repository问题
  3. 利用FS寄存器获取KERNEL32.DLL基址算法的证明
  4. C++STL理论基础
  5. cn101388899 一种web服务器前后台关联审计方法及系统,启明星辰数据库审计精确识别操作者...
  6. 标准化Keras:TensorFlow 2.0中的高级API指南
  7. 【译】Consortium Chain Development
  8. Android 在 NDK 层使用 OpenSSL 进行 RSA 加密
  9. 内核中的page fault copy_from_user
  10. layui 刷新页面_layuimini简洁、清爽、易用的layui后台框架模板