HDU 5274 Dylans loves tree(树链剖分)
【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=5274
【题目大意】
给出一棵树,每个点有一个权值,权值可修改,且大于等于0,询问链上出现次数为奇数的数,题目保证每次询问的链上最多只有一个数出现次数为奇数。如果不存在这样的数,就输出-1。
【题解】
题目等价于求链上点的异或和,树链剖分,线段树维护区间异或和,然后链上查询即可,注意到存在权值为0的特殊情况,所以我们将更新的数字都+1,在最后处理答案的时候-1即可。
【代码】
- #include <cstdio>
- #include <algorithm>
- #include <climits>
- #include <cstring>
- using namespace std;
- const int N=300010;
- int val[N],tot,op,x,d[N],num[N],ed=0,u,w,n,m,i,v[N],vis[N],f[N],g[N],nxt[N],size[N],son[N],st[N],en[N],dfn,top[N],t;char ch;
- void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
- void dfs(int x){
- size[x]=1;
- for(int i=g[x];i;i=nxt[i])if(v[i]!=f[x]){
- f[v[i]]=x,d[v[i]]=d[x]+1;
- dfs(v[i]),size[x]+=size[v[i]];
- if(size[v[i]]>size[son[x]])son[x]=v[i];
- }
- }
- void dfs2(int x,int y){
- if(x==-1)return;
- st[x]=++dfn;top[x]=y;
- if(son[x])dfs2(son[x],y);
- for(int i=g[x];i;i=nxt[i])if(v[i]!=son[x]&&v[i]!=f[x])dfs2(v[i],v[i]);
- en[x]=dfn;
- }
- struct Node{int l,r;int sum;}T[N*4];
- void build(int x,int l,int r){
- T[x].l=l;T[x].r=r;T[x].sum=0;
- if(l==r)return;int mid=(l+r)>>1;
- build(x<<1,l,mid);build((x<<1)|1,mid+1,r);
- }
- void up(int x){T[x].sum=T[x<<1].sum^T[x<<1|1].sum;}
- void update(int x,int k,int val){
- if(T[x].l==k&&T[x].r==k){T[x].sum^=val;return;}
- int mid=(T[x].l+T[x].r)>>1;
- if(k<=mid)update(x<<1,k,val);
- else update((x<<1)|1,k,val); up(x);
- }
- int sum(int x,int l,int r){
- if(l<=T[x].l&&T[x].r<=r)return T[x].sum;
- int mid=(T[x].l+T[x].r)>>1,tmp=0;
- if(l<=mid)tmp^=sum(x<<1,l,r);
- if(r>mid)tmp^=sum((x<<1)|1,l,r);
- return tmp;
- }
- int chain(int x,int y){
- int res=0;
- for(;top[x]!=top[y];x=f[top[x]]){
- if(d[top[x]]<d[top[y]]){int z=x;x=y;y=z;}
- res^=sum(1,st[top[x]],st[x]);
- }if(d[x]<d[y]){int z=x;x=y;y=z;}
- res^=sum(1,st[y],st[x]);
- return res;
- }
- void init(){
- memset(g,dfn=ed=tot=0,sizeof(g));
- memset(v,0,sizeof(v));
- memset(nxt,0,sizeof(nxt));
- memset(son,-1,sizeof(son));
- }
- int cas;
- int main(){
- scanf("%d",&cas);
- while(cas--){
- init();
- scanf("%d%d",&n,&m);
- for(int i=1;i<n;i++){
- scanf("%d%d",&u,&w);
- add(u,w); add(w,u);
- }dfs(1);dfs2(1,1);
- build(1,1,dfn);
- for(int i=1;i<=n;i++){
- scanf("%d",&val[i]); val[i]++;
- update(1,st[i],val[i]);
- }
- while(m--){
- scanf("%d%d%d",&op,&u,&w);
- if(op){
- printf("%d\n",chain(u,w)-1);
- }else{
- update(1,st[u],val[u]^(w+1));
- val[u]=w+1;
- }
- }
- }return 0;
- }
HDU 5274 Dylans loves tree(树链剖分)的更多相关文章
- Hdu 5274 Dylans loves tree (树链剖分模板)
Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...
- hdu 5274 Dylans loves tree (树链剖分 + 线段树 异或)
Dylans loves tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- HDU 5274 Dylans loves tree 树链剖分+线段树
Dylans loves tree Problem Description Dylans is given a tree with N nodes. All nodes have a value A[ ...
- hdu 5274 Dylans loves tree(LCA + 线段树)
Dylans loves tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- HDU 5274 Dylans loves tree(LCA+dfs时间戳+成段更新 OR 树链剖分+单点更新)
Problem Description Dylans is given a tree with N nodes. All nodes have a value A[i].Nodes on tree i ...
- hdu 5274 Dylans loves tree
Dylans loves tree http://acm.hdu.edu.cn/showproblem.php?pid=5274 Time Limit: 2000/1000 MS (Java/Othe ...
- POJ3237 Tree 树链剖分 边权
POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...
- HDU 5614 Baby Ming and Matrix tree 树链剖分
题意: 给出一棵树,每个顶点上有个\(2 \times 2\)的矩阵,矩阵有两种操作: 顺时针旋转90°,花费是2 将一种矩阵替换为另一种矩阵,花费是10 树上有一种操作,将一条路经上的所有矩阵都变为 ...
- HDU 5044 Tree --树链剖分
题意:给一棵树,两种操作: ADD1: 给u-v路径上所有点加上值k, ADD2:给u-v路径上所有边加上k,初始值都为0,问最后每个点和每条边的值,输出. 解法:树链剖分可做,剖出来如果直接用线段树 ...
随机推荐
- 创建、更新、删除文档。 --- Mongodb权威指南阅读。
插入文档: db.foo.insert({ "key" : "value"}); 使用insert插入一个数据,文档中如果没有_id 会自动给文档增加_id. ...
- 生成php所需要的APNS Service pem证书的步骤
1.登录到 iPhone Developer Connection Portal 并点击 App IDs 2.创建一个不使用通配符的 App ID .通配符 ID 不能用于推送通知服务.例如,我们的i ...
- HTML豆ちしき
HTML文档里所有的空白符(空格,Tab,换行,回车)会被浏览器忽略,唯一的例外是空格,对空格的处理方式是所有连续的空格被当成一个空格,不管有一个,还是两个,还是100个.之所以有这样的规则是因为忽略 ...
- php获取网页内容方法 小偷程序 采集程序
抓取到的内容在通过正则表达式做一下过滤就得到了你想要的内容,至于如何用正则表达式过滤,在这里就不做介绍了,有兴趣的,以下就是几种常用的用php抓取网页中的内容的方法.1.file_get_conten ...
- MySQL二进制日志中保存的上下文信息
1.二进制日志中要保存上下文的原因 二进制日志是要在slave端重放的,记录上下文信息,是为了保证主丛数据库的一致.如rand一个随机数,在主上返回的可以有是100,在从上返回的可能就是1000了. ...
- SQL Server MYSQL 检查点的好处
执行检查点时: 如果一个事务不没有提交.日志缓存还是会被更新到磁盘上的物理文件. 这样做就使得大事务commit 时也特别快!
- 在cad中画一条长500mm,垂直90度的线段
视频教程奉上 方法1.点击线段按钮,鼠标指定一点,输入500,再输入<90. 方法2,点击线段按钮,鼠标指定一点,输入500,按tab,再输入90.
- Android手机app启动的时候第一个Activity必须是MainActivity吗
原文:Android手机app启动的时候第一个Activity必须是MainActivity吗 Android手机APP启动的第一个Activity是可以自己设置的,不是必须的MainActivity ...
- Unix/Linux环境C编程入门教程(8) FreeBSD CCPP开发环境搭建
1. FreeBSD是一种自由类Unix操作系统,是由经过BSD.386BSD和4.4BSD发展而来的类Unix的一个重要分支.FreeBSD拥有超过200名活跃开发者和上千名贡献者.FreeBSD被 ...
- Java程序员快速入门Go语言
这篇文章帮助Java程序员快速入门Go语言. 转载至 开源中国社区. http://www.oschina.net 本文将以一个有代表性的例子为开始,以此让Java程序员对Go语言有个初步认识,随后将 ...