2819: Nim

题目:传送门


题解:

   很久之前学博弈的时候看过的一道水题,其实算不上博弈吧...

   直接套上一个裸的树剖啊,把路径上的点值全都xor(xor满足结合率所以就不管那么多随便搞啦)

   dog B 肉老师,竟然不告诉我它卡常,搞得我TLE几百年

  


代码:

 #include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
inline int read()
{
int f=,x=;char ch;
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return f*x;
}
struct node
{
int x,y,next;
}a[];int len,last[];
inline void ins(int x,int y)
{
len++;a[len].x=x;a[len].y=y;
a[len].next=last[x];last[x]=len;
}
struct trnode
{
int l,r,c,lc,rc;
}tr[];int trlen;
inline void bt(int l,int r)
{
int now=++trlen;
tr[now].l=l;tr[now].r=r;tr[now].c=;
tr[now].lc=tr[now].rc=-;
if(l<r)
{
int mid=(tr[now].l+tr[now].r)/;
tr[now].lc=trlen+;bt(l,mid);
tr[now].rc=trlen+;bt(mid+,r);
}
}
inline void change(int now,int p,int c)
{
if(tr[now].l==tr[now].r){tr[now].c=c;return ;}
int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/;
if(p<=mid)change(lc,p,c);
else change(rc,p,c);
tr[now].c=tr[lc].c^tr[rc].c;
}
inline int getsum(int now,int l,int r)
{
if(tr[now].l==l && r==tr[now].r)return tr[now].c;
int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/;
if(r<=mid)return getsum(lc,l,r);
else if(mid+<=l)return getsum(rc,l,r);
return getsum(lc,l,mid)^getsum(rc,mid+,r);
}
int n,fa[],son[],dep[],tot[];
inline void pre_tree_node(int x)
{
son[x]=;tot[x]=;
for(register int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(y!=fa[x])
{
dep[y]=dep[x]+;
fa[y]=x;
pre_tree_node(y);
if(tot[y]>tot[son[x]])son[x]=y;
tot[x]+=tot[y];
}
}
}
int top[],ys[],id,tp;
inline void pre_tree_edge(int x)
{
int tt=tp;top[x]=tp;ys[x]=++id;
if(son[x]!=)pre_tree_edge(son[x]);
for(register int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(y!=son[x] && y!=fa[x])
{
tp=y;
pre_tree_edge(y);
tp=tt;
}
}
}
int sol(int x,int y)
{
int ans=,tx=top[x],ty=top[y];
while(tx!=ty)
{
if(dep[tx]>dep[ty])swap(tx,ty),swap(x,y);
ans^=getsum(,ys[ty],ys[y]);
y=fa[ty];ty=top[y];
}
if(x==y)return ans^getsum(,ys[x],ys[x]);
else
{
if(dep[x]>dep[y])swap(x,y);
return ans^getsum(,ys[x],ys[y]);
}
}
int st[],Q;
char s[];
int main()
{
//freopen("a.in","r",stdin);freopen("a.out","w",stdout);
n=read();for(int i=;i<=n;++i)st[i]=read();
len=;memset(last,,sizeof(last));
for(register int i=;i<n;++i)
{
int x=read(),y=read();
ins(x,y);ins(y,x);
}
fa[]=;dep[]=;pre_tree_node();
id=;tp=;pre_tree_edge();
trlen=;bt(,id);
for(register int i=;i<=n;++i)change(,ys[i],st[i]);
Q=read();
while(Q--)
{
scanf("%s",s+);int x=read(),y=read();
if(s[]=='Q')
{
if(sol(x,y)!=)printf("Yes\n");
else printf("No\n");
}
else change(,ys[x],y);
}
return ;
}

bzoj2819: Nim(博弈+树剖)的更多相关文章

  1. BZOJ:2819 NIM(树链剖分||DFS序 &&NIM博弈)

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

  2. BZOJ2819: Nim 树链剖分

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

  3. bzoj2819 Nim

    题意:给定一棵带点权的树,每次询问用一条路径上的点玩Nim游戏先手是否必胜,支持单点修改. Nim游戏:所有堆的数目异或起来不为0时先手必胜,否则必败. 所以就是单点修改+路径异或和查询. 树剖一发, ...

  4. 博弈论中的Nim博弈

    瞎扯 \(orzorz\) \(cdx\) 聚聚给我们讲了博弈论.我要没学上了,祝各位新年快乐.现在让我讲课我都不知道讲什么,我会的东西大家都会,太菜了太菜了. 马上就要回去上文化课了,今明还是收下尾 ...

  5. Atcoder #017 agc017 D.Game on Tree 树上NIM 博弈

    LINK 题意:树上NIM的模板题,给出一颗树,现有操作删去端点不为根节点的边,其另一端节点都将被移除,不能取者为败 思路:一看就是个NIM博弈题,只是搬到树上进行,树上DFS进行异或 记得#014D ...

  6. BZOJ2819 Nim 【dfn序 + lca + 博弈论】

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

  7. HDU 2509 Nim博弈变形

    1.HDU 2509  2.题意:n堆苹果,两个人轮流,每次从一堆中取连续的多个,至少取一个,最后取光者败. 3.总结:Nim博弈的变形,还是不知道怎么分析,,,,看了大牛的博客. 传送门 首先给出结 ...

  8. HDU 1907 Nim博弈变形

    1.HDU 1907 2.题意:n堆糖,两人轮流,每次从任意一堆中至少取一个,最后取光者输. 3.总结:有点变形的Nim,还是不太明白,盗用一下学长的分析吧 传送门 分析:经典的Nim博弈的一点变形. ...

  9. 【61测试】【dp】【二分】【前缀和】【树剖】

    不要问我为什么昨天考的今天才贴解题报告.. 第一题: 给定3个字符串,求它们的最长公共子序列. 解: 考试时知道肯定是LCS的二维再加一维,用三维,可天堂有路你不走,地狱无门你偏来...灵机一动想出来 ...

随机推荐

  1. 浅谈Websocket、Ajax轮询和长轮询(long polling)

    浅谈Websocket.Ajax轮询和长轮询(long p0ll) 最近看到了一些介绍Websocket的文章,觉得挺有用,所以在这里将自己的对其三者的理解记录一下. 1.什么是Websocket W ...

  2. AMQP及RabbitMQ

    AMQPAMQP协议是一个高级抽象层消息通信协议,RabbitMQ是AMQP协议的实现.它主要包括以下组件: 1.Server(broker): 接受客户端连接,实现AMQP消息队列和路由功能的进程. ...

  3. Python 遍历目录

    代码: 1.递归使用遍历目录 import os def scanfile(path): filelist = os.listdir(path) allfile = [] for filename i ...

  4. alert弹出框 弹出窗口 ----sweetAlert

    推荐一款好用的alert,下面地址是demo,很直观的看到效果,wap可以使用 http://www.dglives.com/demo/sweetalert-master/example/   < ...

  5. Git及Github环境搭建(Windows系统)

    一.github账号注册 1.打开网址https://github.com  注册账号: 二.本地安装Git 1.安装包下载地址:链接:https://pan.baidu.com/s/1smpnJL7 ...

  6. javaee 用Buffered进行对象的写入和读取

    package Zjshuchu; import java.io.Serializable; public class Dog implements Serializable{    private ...

  7. NW.js构建PC收银端安装程序的指南

    1.首先下载nw.js的SDK: https://nwjs.org.cn/download.html 2.SDK目录下新建myapp文件夹: 3.myapp文件夹内新建package.json文件: ...

  8. 单调队列 && 单调栈

    单调队列 && 单调栈 单调队列 维护某个滑动区间的min or max,可用于dp的优化 以维护min为例,采用STL双端队列实现 每次加入元素x前 先检查队首元素==滑动后要删除的 ...

  9. C语言中时钟编程

    目录 C语言中时钟编程 1. 文章目的 2.基本概念 2.1 UTC时间 2.2 UNIX纪元时间 2.3 格林威治时间 (GMT) 3.时间转换 3.1 asctime函数 3.2 ctime函数 ...

  10. 【剑指Offer】28、数组中出现次数超过一半的数字

      题目描述:   数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.   例如:输入如下所示的一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过 ...