BZOJ2819 Nim(DFS序)
题目:单点修改、树链查询。
可以直接用树链剖分做。。
修改是O(QlogN),查询是O(QlogNlogN),Q=N=500000;
听说会超时。。
这题也可以用DFS序来做。
先不看修改,单单查询:可以求出每个点到根的xor值,那么对任意两点的查询就等于xor(u)^xor(v)^val(lca(u,v));
如果有修改:修改仅仅是单个点,而维护的只是点到根的路径,因此修改仅仅会影响到以这个点为根的子树的所有结点到根的信息。
所以用DFS序把子树们化为连续区间用线段树维护,修改本质上是个线段树的区间修改,查询是个单点查询。
每次修改和查询都是O(logN)。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 550000
struct Edge{
int v,nxt;
}edge[MAXN<<];
int NE,head[MAXN];
void addEdge(int u,int v){
edge[NE].v=v; edge[NE].nxt=head[u]; head[u]=NE++;
}
int n,stone[MAXN];
int odr,stack[MAXN],l[MAXN],r[MAXN],dep[MAXN],fa[][MAXN],val[MAXN];
void dfs(){
int top=;
stack[++top]=;
val[]=stone[];
while(top){
int u=stack[top];
if(l[u]){
r[u]=odr; --top;
continue;
}
l[u]=++odr;
for(int i=head[u]; i!=-; i=edge[i].nxt){
int v=edge[i].v;
if(fa[][u]==v) continue;
fa[][v]=u; dep[v]=dep[u]+; val[v]=val[u]^stone[v]; stack[++top]=v;
}
}
} int tree[MAXN<<],N,x,y,z;
void update(int i,int j,int k){
if(x<=i && j<=y){
tree[k]^=z;
return;
}
if(tree[k]){
tree[k<<]^=tree[k]; tree[k<<|]^=tree[k];
tree[k]=;
}
int mid=i+j>>;
if(x<=mid) update(i,mid,k<<);
if(y>mid) update(mid+,j,k<<|);
}
int query(int i,int j,int k){
if(i==j) return tree[k];
if(tree[k]){
tree[k<<]^=tree[k]; tree[k<<|]^=tree[k];
tree[k]=;
}
int mid=i+j>>;
if(x<=mid) return query(i,mid,k<<);
return query(mid+,j,k<<|);
} int lca(int u,int v){
if(dep[u]>dep[v]) swap(u,v);
for(int k=; k<; ++k){
if((dep[v]-dep[u])>>k&){
v=fa[k][v];
}
}
if(v==u) return u;
for(int k=; k>=; --k){
if(fa[k][u]!=fa[k][v]){
u=fa[k][u];
v=fa[k][v];
}
}
return fa[][u];
}
void init(){
dfs();
for(int i=; i<; ++i){
for(int j=; j<=n; ++j){
int t=fa[i-][j];
if(t) fa[i][j]=fa[i-][t];
}
}
for(N=; N<odr; N<<=);
for(int i=; i<=n; ++i){
x=l[i]; y=l[i]; z=val[i];
update(,N,);
}
}
int main(){
int q,a,b;
char op[];
memset(head,-,sizeof(head));
scanf("%d",&n);
for(int i=; i<=n; ++i){
scanf("%d",stone+i);
}
for(int i=; i<n; ++i){
scanf("%d%d",&a,&b);
addEdge(a,b);
addEdge(b,a);
}
init();
scanf("%d",&q);
while(q--){
scanf("%s%d%d",op,&a,&b);
if(op[]=='Q'){
int res;
x=l[a]; res=query(,N,);
x=l[b]; res^=query(,N,);
res^=stone[lca(a,b)];
if(res) puts("Yes");
else puts("No");
}else{
x=l[a]; y=r[a]; z=b^stone[a];
update(,N,);
stone[a]=b;
}
}
return ;
}
BZOJ2819 Nim(DFS序)的更多相关文章
- 【bzoj2819】Nim DFS序+树状数组+倍增LCA
题目描述 著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取.谁不能取谁输.这个游戏是有必胜策略 ...
- [BZOJ 2819]NIM(dfs序维护树上xor值)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2819 分析: 树上的nim游戏,关键就是要判断树上的一条链的异或值是否为0 这个题目有 ...
- BZOJ 2819: Nim dfs序维护树状数组,倍增
1.随机选两个堆v,u,询问若在v到u间的路径上的石子堆中玩Nim游戏,是否有必胜策略,如果有,vfleaking将会考虑将这些石子堆作为初始局面之一,用来坑玩家.2.把堆v中的石子数变为k. 分析: ...
- BZOJ 2819: Nim( nim + DFS序 + 树状数组 + LCA )
虽然vfleaking好像想卡DFS...但我还是用DFS过了... 路径上的石堆异或和=0就是必败, 否则就是必胜(nim游戏). 这样就变成一个经典问题了, 用DFS序+BIT+LCA就可以在O( ...
- 【bzoj2819】Nim(dfs序+树状数组/线段树)
题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=2819 首先根据SG定理,可得若每堆石子数量的异或值为0,则后手必胜,反之先手必胜.于是 ...
- bzoj 2819 Nim(BIT,dfs序,LCA)
2819: Nim Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1596 Solved: 597[Submit][Status][Discuss] ...
- [BZOJ - 2819] Nim 【树链剖分 / DFS序】
题目链接: BZOJ - 2819 题目分析 我们知道,单纯的 Nim 的必胜状态是,各堆石子的数量异或和不为 0 .那么这道题其实就是要求求出树上的两点之间的路径的异或和.要求支持单点修改. 方法一 ...
- BZOJ2819 Nim 【dfn序 + lca + 博弈论】
题目 著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取.谁不能取谁输.这个游戏是有必胜策略的. ...
- BZOJ:2819 NIM(树链剖分||DFS序 &&NIM博弈)
著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取.谁不能取谁输.这个游戏是有必胜策略的.于是v ...
随机推荐
- 理解Java中的接口
一.为什么要使用接口 假如有一个需求:要求实现防盗门的功能.门有"开"和"关"的功能,锁有"上锁"和"开锁"的功能. 分 ...
- Linux Tomcat 简介
如今,基于Web的应用越来越多,传统的Html已经满足不了如今的需求.我们需要一个交互式的Web,于是便诞生了各种Web语言.如Asp,Jsp,Php等.当然,这些语言与传统的语言有着密切的联系,如P ...
- OpenResty(Nginx)+Lua+GraphicsMagick实现缩略图功能
http://www.hopesoft.org/blog/?p=1188 http://www.imagemagick.org/download/ 2.用法 原始图片是input.jpg,尺寸:160 ...
- 获取oracle 表字段,表名,以及主键之类等等的信息。
获取表名: Oracle的user_talbes用于记录了用户表信息. select * from user_tables 获取某个表的字段: USER_TAB_COLS中记录了用户表的列信息.下 ...
- java 异常处理 Throwable Error 和Exception
Java异常类层次结构图: 异常的英文单词是exception,字面翻译就是“意外.例外”的意思,也就是非正常情况.事实上,异常本质上是程序上的错误,包括程序逻辑错误和系统错误. 比如使用 ...
- Windows下的cmd命令行中设置环境编码
我们都知道,Windows下的cmd命令行默认编码是Windows系统的编码,就是ANSI编码或者说是GBK编码的,这样我们编写的很多应用比如php编写utf-8编码的应用在命令行下面运行时都会出现乱 ...
- 【HTTP协议】响应头中的Content-Length和Transfer-Encoding
来源: http://blog.csdn.net/superhosts/article/details/8737434 http://bbs.csdn.net/topics/390384017 对于h ...
- border-box
box-sizing属性可以为三个值之一:content-box(default),border-box,padding-box. content-box,border和padding不计算入wi ...
- GLSL
变量修饰符 修饰符给出了变量的特殊含义,GLSL中有如下修饰符: ·const – 声明一个编译期常量. ·attribute– 随不同顶点变化的全局变量,由OpenGL应用程序传给顶点shader. ...
- 三种配置linux环境变量的方法(以java为例)
1.先确认是否为openjdk:参考 2. 修改/etc/profile文件 如果你的计算机仅仅作为开发使用时推荐使用这种方法,因为所有用户的shell都有权使用这些环境变量,可能会给系统带来安全性 ...