【手动开栈】【dfs序】【树状数组】【Tarjan】bzoj2819 Nim
考虑树状数组区间修改(只对其子树的答案有影响)点查询,每个点记录的是它到根路径上的权值异或和。
答案时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的更多相关文章
- [BZOJ1103][POI2007]大都市meg dfs序+树状数组
Description 在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了.不过,她经常回忆起以前在乡间漫步的情景.昔日,乡下有依次编号为1..n ...
- 【BZOJ】2819: Nim(树链剖分 / lca+dfs序+树状数组)
题目 传送门:QWQ 分析 先敲了个树链剖分,发现无法AC(其实是自己弱,懒得debug.手写栈) 然后去学了学正解 核心挺好理解的,$ query(a) $是$ a $到根的异或和. 答案就是$ l ...
- 【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树
题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...
- 【bzoj2819】Nim DFS序+树状数组+倍增LCA
题目描述 著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取.谁不能取谁输.这个游戏是有必胜策略 ...
- NOI 2011 阿狸的打字机 (AC自动机+dfs序+树状数组)
题目大意:略(太长了不好描述) 良心LOJ传送门 先对所有被打印的字符串建一颗Trie树 观察数据范围,并不能每次打印都从头到尾暴力建树,而是每遍历到一个字符就在Trie上插入这个字符,然后记录每次打 ...
- HDU 3887:Counting Offspring(DFS序+树状数组)
http://acm.hdu.edu.cn/showproblem.php?pid=3887 题意:给出一个有根树,问对于每一个节点它的子树中有多少个节点的值是小于它的. 思路:这题和那道苹果树是一样 ...
- HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...
- 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 ...
- BZOJ 2434: [Noi2011]阿狸的打字机( AC自动机 + DFS序 + 树状数组 )
一个串a在b中出现, 那么a是b的某些前缀的后缀, 所以搞出AC自动机, 按fail反向建树, 然后查询(x, y)就是y的子树中有多少是x的前缀. 离线, 对AC自动机DFS一遍, 用dfs序+树状 ...
- 【bzoj3881】[Coci2015]Divljak AC自动机+树链的并+DFS序+树状数组
题目描述 Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. ...
随机推荐
- CentOS ninimal 安装后没有桌面-yellowcong
昨天,安装Centos后,发现没有桌面,主要是没有安装桌面环境导致 的这个问题,我们需要做的第一步是,安装一个桌面(GNOME Desktop,命令:yum groupinstall -y " ...
- LaTeX的图片插入及排版[转]
LaTeX中一般只直接支持插入eps(Encapsulated PostScript)格式的图形文件, 因此在图片插入latex文档之前应先设法得到图片的eps格式的文件. UNIX下的各种应用软件都 ...
- Robot POJ - 1376
The Robot Moving Institute is using a robot in their local store to transport different items. Of co ...
- python 闭包与装饰器
1.闭包--返回子函数名 作用:使用子函数之外的父函数的变量 闭包就是你调用了一个函数a,这个函数a反悔了一个子函数名b,这个返回的函数b就叫做闭包 代码举例 def a(): test = 'aa' ...
- 小白科普之JavaScript的DOM模型
微信公众号“前端大全”推送了一篇名为“通俗易懂的来讲讲DOM”的文章,把javascript原生DOM相关内容讲解的很详细.仔细读了一遍,觉得整理总结的不错,对自己也很使用,所以把内容整理过来,并根据 ...
- poj 2406 Power Strings(kmp循环节)
题目链接:http://poj.org/problem?id=2406 题目大意:如果n%(n-next[n])==0,则存在重复连续子串,长度为n-next[n]. 例如: a b ...
- django执行sql
http://docs.30c.org/djangobook2/chapter10/ def first_names(self, last_name): cursor = connection.cur ...
- Makefile target dependency
Makefile ..... all: T1 T2 T1: @echo "<===" $@ T2: @echo "<===" $@ ..... ma ...
- Python Requests 小技巧总结
关于 Python Requests ,在使用中,总结了一些小技巧把,分享下. 1:保持请求之间的Cookies,我们可以这样做. import requests self.session = req ...
- PHP定时执行
参考一 test.bat D:\myamp\php\php.exe -q D:\myamp\Apache\htdocs\dingshi.php dingshi.php <?php ignore_ ...