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

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

修改是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. cocos基础教程(7)动作与动画

    动作类(Action) 动作类(Action)是所有动作的基类,它创建的一个对象代表一个动作.动作作用于Node,因此每个动作都需要由Node对象执行.动作类(Action)作为基类,实际上是一个接口 ...

  2. java笔记--适配器模式的运用

    适配器模式的运用 --如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3884785.html "谢谢-- 主要应用: 可以在符合 ...

  3. Eclipse的模板设置代码

    Eclipse Java注释模板设置详解   设置注释模板的入口: Window->Preference->Java->Code Style->Code Template 然后 ...

  4. centos7下cups + samba共打印服务的教程

    centos7系统我们用到的不多但是这款系统比centos6功能要强大了不少,下文来介绍一篇centos7下cups + samba,共打印服务的例子,具体如下所示.   这个算是rhce课程的篇外篇 ...

  5. [另开新坑] 算导v3 #26 最大流 翻译

    26 最大流 就像我们可以对一个路网构建一个有向图求最短路一样,我们也可以将一个有向图看成是一个"流量网络(flow network)",用它来回答关于流的问题. Just as ...

  6. 用Python操纵MySQL

    本例用Python操纵MySQL,从指定文件读取数据,并对数据进行处理,处理之后批量插入MySQL. 贴上代码: # -*- coding: gbk -*- import re import MySQ ...

  7. Reverse Linked List | & ||

    Reverse Linked List I Reverse a linked list. Example For linked list 1->2->3, the reversed lin ...

  8. Sharepoint 2010 创建栏 计算栏

    SharePoint 创建栏时,可以添加计算字段, 网上查了查,相关资料如下: http://wenku.baidu.com/view/936239e9b8f67c1cfad6b88f.html ht ...

  9. DP:Multiplication Puzzle(POJ 1651)

    卡片游戏 题目大意:给你一排卡片,你可以从从中抽一些卡片(但是不能抽最左和最右的卡片),每张卡片上有一个数字,当你从中抽出一张卡片后,你将得卡片的数字和卡片左右两张卡片的数字的乘积的分数,问当剩下最左 ...

  10. Codeforces 424C(异或)

    Magic Formulas Time Limit: 2000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u Subm ...