题目:单点修改、树链查询。

可以直接用树链剖分做。。

修改是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序)的更多相关文章

  1. 【bzoj2819】Nim DFS序+树状数组+倍增LCA

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

  2. [BZOJ 2819]NIM(dfs序维护树上xor值)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2819 分析: 树上的nim游戏,关键就是要判断树上的一条链的异或值是否为0 这个题目有 ...

  3. BZOJ 2819: Nim dfs序维护树状数组,倍增

    1.随机选两个堆v,u,询问若在v到u间的路径上的石子堆中玩Nim游戏,是否有必胜策略,如果有,vfleaking将会考虑将这些石子堆作为初始局面之一,用来坑玩家.2.把堆v中的石子数变为k. 分析: ...

  4. BZOJ 2819: Nim( nim + DFS序 + 树状数组 + LCA )

    虽然vfleaking好像想卡DFS...但我还是用DFS过了... 路径上的石堆异或和=0就是必败, 否则就是必胜(nim游戏). 这样就变成一个经典问题了, 用DFS序+BIT+LCA就可以在O( ...

  5. 【bzoj2819】Nim(dfs序+树状数组/线段树)

    题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=2819 首先根据SG定理,可得若每堆石子数量的异或值为0,则后手必胜,反之先手必胜.于是 ...

  6. bzoj 2819 Nim(BIT,dfs序,LCA)

    2819: Nim Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1596  Solved: 597[Submit][Status][Discuss] ...

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

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

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

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

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

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

随机推荐

  1. unity3d的四元数 Quaternion

    原地址:http://www.cnblogs.com/88999660/archive/2013/04/02/2995074.html 今天准备学习和研究下unity3d的四元数 Quaternion ...

  2. C#开发实例 鼠标篇

    鼠标的操作控制: 鼠标是计算机的一个重要组成部分,有很多默认的设置,如双击时间间隔,闪烁频率,移动速度等,本篇使用C#获取这些基本的信息. 1.1获取鼠标信息 ①实例001 获取鼠标双击时间间隔 主要 ...

  3. dex和odex相互转换

    一.dex和odex dex是安卓dalvik虚拟机的可执行文件,可以在导出的apk文件里用解压缩软件直接打开.odex是经过优化过的dex.odex一种是从apk程序中提取出来的,与apk文件存放在 ...

  4. 《OpenCV入门》(三)

    这部分主要讲形态学的,回头把代码跑跑再来说下代码的感受:http://blog.csdn.net/poem_qianmo/article/details/24599073

  5. 查看现有运行的linux服务器有多少内存条

    i161 admin # ssh 192.168.5.209 dmidecode | grep 'Ending Address' -B1 -A2    Starting Address: 0x0000 ...

  6. chrome打开本地文件目录

    chrome地址栏输入: file:///

  7. 《转》Visual Studio 2010 终极定制安装精简方法

    打开VS2010安装目录下的 Setup 文件夹,找到 baseline.dat 文件和 vs_setup.pdi 文件还有一个 locdata.ini 文件,是对应的. 这些都是文本文件,用记事本就 ...

  8. Best Time to Buy and Sell Stock | & || & III

    Best Time to Buy and Sell Stock I Say you have an array for which the ith element is the price of a ...

  9. try---catch异常处理

    try { sc.Send(msg); return; } catch (Exception ex) { //AlertInfo("发送失败," + ex); return ; }

  10. cocos2d-x如何解决图片显示模糊问题

    转载http://zhidao.baidu.com/link?url=JTUKP5quGfMQixLZSvtC2XlKMkQDyQbYW72_DRyD6KDRpkLs8_6poQtKkwsyqzU8q ...