hdu5274 - Dylans loves tree(树链剖分)
来源:互联网 发布:百度算法大全 编辑:程序博客网 时间:2024/05/16 16:23
Dylans loves tree
Accepts: 37
Submissions: 262
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 131072/131072 K (Java/Others)
问题描述
Dylans有一棵N个点的树。每个点有点权。树上节点标号为1∼N。
他得到了Q个询问,形式如下:
①0 x y:把第x个点的点权修改为y。
②1 x y:对于x∼y路径上的每一种点权,是否都出现偶数次?
保证每次询问的路径上最多只有一种点权的出现次数是奇数次。
1≤N,Q≤100000, 点权A[i]∈N,且都 ≤100000
输入描述
第一行一个正整数T表示数据组数(T≤3且最多只有一组数据N>1000)
第一行两个数N、Q表示树的点数和询问个数。
接下来N−1行每行一对数(x,y)表示树上的一条边。
接下来一行N个数表示每个点的点权。
接下来Q行每行三个数(opt,x,y)表示询问。
输出描述
对于每个②询问,如果全是偶数输出“-1”,否则输出出现奇数次的权值。
输入样例
1
3 2
1 2
2 3
1 1 1
1 1 2
1 1 3
输出样例
-1
1
Hint
hack数据里N和Q必须小于等于10000,且对于读入的每一行末尾不应该有多余的空格。
官方题解:
题目里有一个很神奇的性质:路径上最多只有一个数出现奇数次。
这应该马上想到异或。因为异或两次和没异或是等价的。此外异或满足区间减性质。
因为有修改,我们很自然地想到用数据结构维护。
最无脑的就是直接上树链剖分或是Splay维护区间xor值即可。
仔细想一想,发现可以利用LCA消去“树上路径”,转化为根到x路径上求xor值。
我们可以很经典地直接使用线段树或树状数组维护dfs序。
(然而BC不给我卡log2。。。呜呜呜)
有一个很强的trick就是权值可以为0!
所以比如路径上有3个0,虽然他们xor值还是0,但是他们是出现了奇数次。
我特意把A[i]说成∈自然数集而不是[0,100000],就是想尽量不被发现。
怎么避免呢?单独维护0的情况?
有一个很简单的解决方案:直接把读入时所有权值+1,输出的时候再-1即可!
时间复杂度为
#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>#pragma comment(linker,"/STACK:1024000000,1024000000")using namespace std;const int maxn=100010;int N,Q;int head[maxn],tot;int num[maxn];int son[maxn];int w[maxn];int fw[maxn];int fa[maxn];int pos;int top[maxn];int dep[maxn];int A[maxn];struct node{ int v,next;}edge[maxn*2];void init(){ tot=pos=0; memset(head,-1,sizeof(head)); memset(son,-1,sizeof(son));}void add_edge(int u,int v){ edge[tot].v=v; edge[tot].next=head[u]; head[u]=tot++;}void dfs1(int u,int f,int depth){ dep[u]=depth; num[u]=1; fa[u]=f; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(v==f)continue; dfs1(v,u,depth+1); num[u]+=num[v]; if(son[u]==-1||num[son[u]]<num[v]) son[u]=v; }}void dfs2(int u,int sp){ top[u]=sp; w[u]=++pos; fw[pos]=u; if(son[u]!=-1)dfs2(son[u],sp); for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(v!=fa[u]&&v!=son[u]) dfs2(v,v); }}struct IntervalTree{ int X[maxn<<2]; void build(int o,int l,int r) { X[o]=0; if(l==r) { X[o]=A[fw[l]]+1; return ; } int mid=(l+r)>>1; build(o<<1,l,mid); build(o<<1|1,mid+1,r); pushup(o); } void pushup(int o) { X[o]=((X[o<<1])^(X[o<<1|1])); } void update(int o,int l,int r,int x,int y) { if(l==r) { X[o]=y; return ; } int mid=(l+r)>>1; if(x<=mid)update(o<<1,l,mid,x,y); else update(o<<1|1,mid+1,r,x,y); pushup(o); } int query(int o,int l,int r,int q1,int q2) { if(q1<=l&&r<=q2) return X[o]; int mid=(l+r)>>1; int ans=0; if(q1<=mid)ans^=query(o<<1,l,mid,q1,q2); if(q2>mid)ans^=query(o<<1|1,mid+1,r,q1,q2); return ans; }}tree;int Query(int x,int y){ int ans=0; int f1=top[x],f2=top[y]; while(f1!=f2) { if(dep[f1]<dep[f2]) { swap(x,y); swap(f1,f2); } ans^=tree.query(1,1,N,w[f1],w[x]); x=fa[f1],f1=top[x]; } if(dep[x]>dep[y])swap(x,y); ans=(ans^(tree.query(1,1,N,w[x],w[y]))); return ans?ans-1:-1;}int main(){ int T,u,v; int op,x,y; scanf("%d",&T); while(T--) { scanf("%d%d",&N,&Q); init(); for(int i=1;i<N;i++) { scanf("%d%d",&u,&v); add_edge(u,v); add_edge(v,u); } for(int i=1;i<=N;i++)scanf("%d",&A[i]); dfs1(1,0,0); dfs2(1,1); tree.build(1,1,N); while(Q--) { scanf("%d%d%d",&op,&x,&y); if(op==0)tree.update(1,1,N,w[x],y+1); else printf("%d\n",Query(x,y)); } } return 0;}
- hdu5274 - Dylans loves tree(树链剖分)
- hdu5274 Dylans loves tree
- HDU5274.Dylans loves tree
- HDU5274 Dylans loves tree(树链剖分线段树)
- HDU5274 Dylans loves tree(树链剖分+异或)
- hdu5274 Dylans loves tree LCA+线段树
- HDU5274 Dylans loves tree(树链剖分)很巧的点权更新
- HDU 5274 Dylans loves tree 树链剖分(水)
- HDOJ 5274 Dylans loves tree
- BestCoder #45 1003 Dylans loves tree
- 【线段树】 HDOJ 5274 Dylans loves tree
- hdu 5274 Dylans loves tree 树剖
- hdu 5274 Dylans loves tree && BestCoder Round #45
- HDU 5274 Dylans loves tree(LCA+dfs时间戳+成段更新 OR 树链剖分+单点更新)
- Dylans loves numbers
- Dylans loves sequence
- HDU5273-Dylans loves sequence
- HDU5273--Dylans loves sequence
- Base64编码的 换行 转义
- Linux 下模拟Http 的get or post请求(curl和wget两种方法)
- MySQL详解(14)----------事务处理
- linux系统进入单用户模式
- Mongodb Windows 集群
- hdu5274 - Dylans loves tree(树链剖分)
- java 异常小结
- SAP中PDF文件本地保存方法
- RGB颜色原理
- C# 如何扩展方法
- 宏和函数的区别
- jquery cookie用法(获取cookie值,删除cookie)
- Jboss调优
- listView下拉刷新加载数据详解