考虑树状数组区间修改(只对其子树的答案有影响)点查询,每个点记录的是它到根路径上的权值异或和。

答案时query(L)^query(R)^a[lca]。

这种方法在支持区间加法、减法的树上询问的时候可以避免树链剖分。

可能爆栈,考虑手动开栈。(诶诶Tarjan预处理lca的时候怎么没手动开栈?不要在意^_^)

实际上不会爆的。

#include<cstdio>
#include<stack>
#include<algorithm>
#include<queue>
#include<cmath>
#include<vector>
using namespace std;
#define N 500001
typedef pair<int,int> Point;
vector<Point>ask[N];
int n,a[N],b[N],m,ancestor[N];
int en,first[N],next[N<<1],v[N<<1];
int FA[N],rank[N],lcas[N];
void AddEdge(const int &U,const int &V)
{
v[++en]=V;
next[en]=first[U];
first[U]=en;
}
int findroot(int x){return FA[x]==x?x:findroot(FA[x]);}
void Union(int x,int y)
{
int U=findroot(x);
int V=findroot(y);
if(rank[U]<rank[V]) FA[U]=V;
else
{
FA[V]=U;
if(rank[U]==rank[V]) ++rank[U];
}
}
bool vis[N];
void LCA(int U,int Fa)
{
ancestor[U]=U;
for(int i=first[U];i;i=next[i])
if(v[i]!=Fa)
{
LCA(v[i],U);
Union(U,v[i]);
ancestor[findroot(U)]=U;
}
vis[U]=1;
for(int i=0;i<ask[U].size();i++)
if(vis[ask[U][i].first])
lcas[ask[U][i].second]=ancestor[findroot(ask[U][i].first)];
}
stack<int>st;
queue<int>q;
int tot,Ls[N],Rs[N],root=1;
void dfs()
{
st.push(1);
Ls[1]=++tot;
b[1]=a[1];
while(!st.empty())
{
int U=st.top(); bool flag=0;
for(int i=first[U];i;i=next[i])
if(!Ls[v[i]])
{
Ls[v[i]]=++tot;
b[v[i]]=(a[v[i]]^b[U]);
st.push(v[i]);
first[U]=next[i];
flag=1;
break;
}
if(!flag)
{
Rs[U]=tot;
st.pop();
}
}
}
int d[N];
void add_node(int p,const int &v){for(;p<=n;p+=(p&(-p)))d[p]^=v;}
void add_range(const int &L,const int &R,const int &v){add_node(L,v);if(R!=n)add_node(R+1,v);}
int query(int p){int res=0;for(;p;p-=(p&(-p)))res^=d[p];return res;}
int A[N],B[N]; char op[N][2];
int main()
{
int x,y;
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
FA[i]=i;
scanf("%d",&a[i]);
}
for(int i=1;i<n;++i)
{
scanf("%d%d",&x,&y);
AddEdge(x,y);
AddEdge(y,x);
}
scanf("%d",&m);
for(int i=1;i<=m;++i)
{
scanf("%s%d%d",op[i],&A[i],&B[i]);
if(op[i][0]=='Q')
{
ask[A[i]].push_back(make_pair(B[i],i));
ask[B[i]].push_back(make_pair(A[i],i));
}
}
LCA(1,0);
dfs();
for(int i=1;i<=n;++i) add_range(Ls[i],Ls[i],b[i]);
for(int i=1;i<=m;++i)
if(op[i][0]=='Q') puts((query(Ls[A[i]])^query(Ls[B[i]])^a[lcas[i]])?"Yes":"No");
else
{
add_range(Ls[A[i]],Rs[A[i]],a[A[i]]^B[i]);
a[A[i]]=B[i];
}
return 0;
}

【手动开栈】【dfs序】【树状数组】【Tarjan】bzoj2819 Nim的更多相关文章

  1. [BZOJ1103][POI2007]大都市meg dfs序+树状数组

    Description 在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了.不过,她经常回忆起以前在乡间漫步的情景.昔日,乡下有依次编号为1..n ...

  2. 【BZOJ】2819: Nim(树链剖分 / lca+dfs序+树状数组)

    题目 传送门:QWQ 分析 先敲了个树链剖分,发现无法AC(其实是自己弱,懒得debug.手写栈) 然后去学了学正解 核心挺好理解的,$ query(a) $是$ a $到根的异或和. 答案就是$ l ...

  3. 【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树

    题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...

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

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

  5. NOI 2011 阿狸的打字机 (AC自动机+dfs序+树状数组)

    题目大意:略(太长了不好描述) 良心LOJ传送门 先对所有被打印的字符串建一颗Trie树 观察数据范围,并不能每次打印都从头到尾暴力建树,而是每遍历到一个字符就在Trie上插入这个字符,然后记录每次打 ...

  6. HDU 3887:Counting Offspring(DFS序+树状数组)

    http://acm.hdu.edu.cn/showproblem.php?pid=3887 题意:给出一个有根树,问对于每一个节点它的子树中有多少个节点的值是小于它的. 思路:这题和那道苹果树是一样 ...

  7. HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...

  8. Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+树状数组

    C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...

  9. BZOJ 2434: [Noi2011]阿狸的打字机( AC自动机 + DFS序 + 树状数组 )

    一个串a在b中出现, 那么a是b的某些前缀的后缀, 所以搞出AC自动机, 按fail反向建树, 然后查询(x, y)就是y的子树中有多少是x的前缀. 离线, 对AC自动机DFS一遍, 用dfs序+树状 ...

  10. 【bzoj3881】[Coci2015]Divljak AC自动机+树链的并+DFS序+树状数组

    题目描述 Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. ...

随机推荐

  1. POJ3169:Layout(差分约束)

    Layout Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15705   Accepted: 7551 题目链接:http ...

  2. POJ2112:Optimal Milking(Floyd+二分图多重匹配+二分)

    Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 20262   Accepted: 7230 ...

  3. event对象和事件冒泡

    <!DOCTYPE HTML><html><head> <meta charset="utf-8"> <title>无标 ...

  4. PHP设计模式-工厂模式、单例模式、注册模式

    本文参考慕课网<大话PHP设计模式>-第五章内容编写,视频路径为:http://www.imooc.com/video/4876 推荐阅读我之前的文章:php的设计模式 三种基本设计模式, ...

  5. js实现快速排序的方法

    因为面试面到了这个问题,所以写一下,加深印象,有两种方法 第一种是通过两个for循环,每一次对比相邻两个数据的大小,小的排在前面,如果前面的数据比后面的大就交换这两个数的位置,这个方法就是比较次数太多 ...

  6. cxf+spring发布webservice和调用

    maven项目配置http://cxf.apache.org/docs/using-cxf-with-maven.html <properties> <cxf.version> ...

  7. MySQL实现分页查询

    imit 基本实现方式 一般情况下,客户端通过传递 pageNo(页码).pageSize(每页条数)两个参数去分页查询数据库中的数据,在数据量较小(元组百/千级)时使用 MySQL自带的 limit ...

  8. 【uva11019-Matrix Matcher】AC自动机+优化+记录

    http://acm.hust.edu.cn/vjudge/problem/33057 题意:在二维文本串T中查找一个二维模板串P出现了多少次. 题解: 拆分模板串P的每一行,建AC自动机.拆分文本串 ...

  9. bzoj 2435 BFS

    我们可以先将无根树变成有根树,随便选一个点当根就行了,我们选1,bfs求出来每个点 的size值,代表以它为根节点的子树中有多少个节点,(dfs可能会爆栈),然后再对于每一条 边算就好了 我tle了, ...

  10. 流程控制 while循环 运算符

    具体知识戳这里 可变数据类型:在id不变的情况下,数据类型内部的元素(value)可以改变 如:列表,字典 不可变类型:value改变,id也跟的改变 如:数字.字符.布尔类型 运算符 #算数运算符# ...