BestCoder #45 1003 Dylans loves tree
来源:互联网 发布:创维网络电视50价格 编辑:程序博客网 时间:2024/05/16 11:55
problem
题意
- 给定一棵树,并给定在这棵树上的两种操作。一种操作是改变一个节点的权值,另外一个操作是对两个节点之间的路径上的权值进行统计,如果每个权值出现的次数都是偶数,输出-1,否则输出出现次数为奇数的权值(保证只有一个)
思路
- 这题是一个DFS序的模板题。首先想到,我们获得这棵树的DFS序,对于这个序列,我们可以去维护区间的异或和。由于是单点修改区间查询,可以用树状数组也可以直接写线段树。然后对于每个询问,我们查询出每个点到根的异或和(这里直接用DFS序中到根节点的异或和即可,因为如果一个结点不在其到根节点的路径上,其会出现两次,异或和为0),然后求出这两个结点的LCA,再异或LCA的权值。注意这个地方,如果一个结点权值为0,会出错。所以这里要进行处理(把权值都加1,输出答案的时候减1)。LCA用倍增法、Tarjan、RMQ都可以。
- 这题HDU略坑,交G++一直爆栈。然而没必要去管这个。。交C++就过了。
- 利用了G++开栈的代码,成功在G++下AC。。
AC代码
g++开栈代码
register char *_sp __asm__("rsp");int main(){ const int size = 64*1024*1024; static char *sys,*mine(new char[size]+size-4096); sys = _sp;_sp = mine;mmain();_sp = sys; return 0;}
#include <iostream>#include <cstdio>#include <vector>#include <algorithm>#include <cstring>#include <cmath>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;const int MAXN = 110000;int cnt,head[MAXN],dep[MAXN],p[MAXN][20],tot;int st[MAXN],ed[MAXN];int sum[MAXN<<3];int n,q;void update(int pos,int c,int l,int r,int rt){ if(l == r){ sum[rt] = c; return; } int m = (l+r)>>1; if(pos <= m)update(pos,c,lson); else update(pos,c,rson); sum[rt] = sum[rt<<1] ^ sum[rt<<1|1];}int query(int L,int R,int l,int r,int rt){ if(l>=L && R>=r){ return sum[rt]; } int ret = 0; int m = (l+r)>>1; if(L <= m)ret ^= query(L,R,lson); if(R > m)ret ^= query(L,R,rson); return ret;}struct Edge{ int u,v; int next;}e[MAXN<<1];void addedge(int u,int v){ e[cnt].u = u,e[cnt].v = v,e[cnt].next = head[u],head[u] = cnt++; e[cnt].u = v,e[cnt].v = u,e[cnt].next = head[v],head[v] = cnt++;}void dfs(int u){ st[u] = tot++; for(int i=head[u];i!=-1;i=e[i].next){ int v = e[i].v; if(!dep[v]){ dep[v] = dep[u] + 1; p[v][0] = u; dfs(v); } } ed[u] = tot++;}void init(){ cnt = 0; tot = 1; memset(head,-1,sizeof(head)); memset(p,-1,sizeof(p)); memset(dep,0,sizeof(dep));}int LCA(int a,int b){ if(dep[a]<dep[b])swap(a,b); int i; for(i = 0;(1<<i)<=dep[a];i++); i--; for(int j=i;j>=0;j--) if(dep[a]-(1<<j)>=dep[b]) a = p[a][j]; if(a == b)return a; for(int j=i;j>=0;j--){ if(p[a][j]!=-1 && p[a][j] != p[b][j]){ a = p[a][j]; b = p[b][j]; } } return p[a][0];}int u,v;int main(){ int T; cin>>T; while(T--){ scanf("%d%d",&n,&q); init(); for(int i=0;i<n-1;i++){ scanf("%d%d",&u,&v); addedge(u,v); } dep[1] = 1; dfs(1); for(int j=1;(1<<j)<=n;j++) for(int i=1;i<=n;i++) if(p[i][j-1] != -1) p[i][j] = p[p[i][j-1]][j-1]; tot--; memset(sum,0,sizeof(sum)); //for(int i=1;i<=n;i++)printf("%d ",st[i]); //printf("tot : %d\n",tot); for(int i=1;i<=n;i++){ scanf("%d",&u); update(st[i],u+1,1,tot,1),update(ed[i],u+1,1,tot,1); } while(q--){ int op,x,y; scanf("%d%d%d",&op,&x,&y); if(op == 0){ update(st[x],y+1,1,tot,1),update(ed[x],y+1,1,tot,1); }else{ int ansx = query(1,st[x],1,tot,1),ansy = query(1,st[y],1,tot,1); int lca = LCA(x,y),anslca =query(st[lca],st[lca],1,tot,1); //printf("ansx:%d ansy:%d lca:%d\n",ansx,ansy,lca); int ans = ansx ^ ansy ^ anslca; if( ans == 0)puts("-1"); else printf("%d\n",ans-1); } } } return 0;}
0 0
- BestCoder #45 1003 Dylans loves tree
- hdu 5274 Dylans loves tree && BestCoder Round #45
- hdu5274 Dylans loves tree
- HDU5274.Dylans loves tree
- HDOJ 5274 Dylans loves tree
- hdu5274 - Dylans loves tree(树链剖分)
- HDU 5273 Dylans loves sequence——BestCoder Round #45(DP or 树状数组)
- HDU 5272 Dylans loves numbers——BestCoder Round #45(模拟)
- 【线段树】 HDOJ 5274 Dylans loves tree
- hdu 5274 Dylans loves tree 树剖
- hdu5274 Dylans loves tree LCA+线段树
- HDU5274 Dylans loves tree(树链剖分线段树)
- HDU5274 Dylans loves tree(树链剖分+异或)
- HDU 5274 Dylans loves tree 树链剖分(水)
- Dylans loves numbers
- Dylans loves sequence
- HDU5273-Dylans loves sequence
- HDU5273--Dylans loves sequence
- IO-字节流与字符流
- maven 之中央仓库和私有仓库实战
- LeetCode 题解(111): Longest Valid Parentheses
- 零基础项目制学习python(二)
- Algorithms—123.Best Time to Buy and Sell Stock III
- BestCoder #45 1003 Dylans loves tree
- 查看android程序的CPU和内存消耗情况
- 黑马程序员---多线程
- LeetCode——Plus One
- 黑马程序员-线程
- Docker ubuntu 安装
- 用latex排版中的对象旋转问题
- 进程间通信(10) - 网络套接字(socket)[1]
- 将自己的写的 maven 构件发布到 nexus 私服