Hdu 5274 Dylans loves tree (树链剖分模板)
2017-05-05 11:10
369 查看
Hdu 5274 Dylans loves tree (树链剖分模板)
题目传送门
#include <queue> #include <cmath> #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include <vector> #define ll long long #define inf 1000000000LL #define mod 1000000007 using namespace std; int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-')f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*f; } const int N=1e5+10; const int M=2e5+10; int n,q,cnt,sz; int v ,dep ,size ,head ,fa ; int pos ,bl ; struct data{int to,next;}e[M]; struct seg{int l,r,sum;}t[N<<2]; void insert(int u,int v) { e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt; e[++cnt].to=u;e[cnt].next=head[v];head[v]=cnt; } void init() { sz=cnt=0; dep[1]=0; memset(head,0,sizeof(head)); memset(size,0,sizeof(size)); n=read();q=read(); int x,y; for(int i=1;i<n;i++) { x=read();y=read(); insert(x,y); } for(int i=1;i<=n;i++) v[i]=read(); } void dfs1(int x) { size[x]=1; for(int i=head[x];i;i=e[i].next) { if(e[i].to==fa[x])continue; dep[e[i].to]=dep[x]+1; fa[e[i].to]=x; dfs1(e[i].to); size[x]+=size[e[i].to]; } } void dfs2(int x,int chain) { int k=0;sz++; pos[x]=sz;//分配x结点在线段树中的编号 bl[x]=chain; for(int i=head[x];i;i=e[i].next) if(dep[e[i].to]>dep[x]&&size[e[i].to]>size[k]) k=e[i].to;//选择子树最大的儿子继承重链 if(k==0)return; dfs2(k,chain); for(int i=head[x];i;i=e[i].next) if(dep[e[i].to]>dep[x]&&k!=e[i].to) dfs2(e[i].to,e[i].to);//其余儿子新开重链 } void build(int k,int l,int r)//建线段树 { t[k].l=l;t[k].r=r; t[k].sum=0; if(l==r)return; int mid=(l+r)>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); } void change(int k,int x,int y)//线段树单点修改 { int l=t[k].l,r=t[k].r,mid=(l+r)>>1; if(l==r){t[k].sum=y;return;} if(x<=mid)change(k<<1,x,y); else change(k<<1|1,x,y); t[k].sum=t[k<<1].sum^t[k<<1|1].sum; } int querysum(int k,int x,int y)//线段树区间求异或 { int l=t[k].l,r=t[k].r,mid=(l+r)>>1; if(l==x&&y==r)return t[k].sum; if(y<=mid)return querysum(k<<1,x,y); else if(x>mid)return querysum(k<<1|1,x,y); else {return querysum(k<<1,x,mid)^querysum(k<<1|1,mid+1,y);} } int solvesum(int x,int y) { int sum=0; while(bl[x]!=bl[y]) //bl[x] 点x的链哈希值 { if(dep[bl[x]]<dep[bl[y]])swap(x,y); sum^=querysum(1,pos[bl[x]],pos[x]); x=fa[bl[x]]; } if(pos[x]>pos[y])swap(x,y); sum^=querysum(1,pos[x],pos[y]); return sum; } void solve() { build(1,1,sz); for(int i=1;i<=n;i++) change(1,pos[i],v[i]+1); //pos[i]: i节点的哈希值 int op,ans,x,y;; for(int i=1;i<=q;i++) { op=read();x=read();y=read(); if(op==0){v[x]=y;change(1,pos[x],y+1);} else { ans=solvesum(x,y); printf("%d\n",ans-1); } } } int main() { int T; T=read(); while(T--){ init(); dfs1(1); dfs2(1,1); solve(); } return 0; }
相关文章推荐
- Dylans loves tree(hdu 5274 树链剖分+线段树模板)
- HDU 5274 Dylans loves tree(LCA+dfs时间戳+成段更新 OR 树链剖分+单点更新)
- hdu 5274 Dylans loves tree (树链剖分+异或和)
- HDU 5274 Dylans loves tree(LCA+dfs时间戳+成段更新 OR 树链剖分+单点更新)
- HDU 5274 Dylans loves tree(树链剖分)
- HDU 5274 Dylans loves tree(DFS序+线段树+LCA离线查询模板+手动扩大内存)
- hdu 5274 Dylans loves tree 树剖
- hdu Dylans loves tree [LCA] (树链剖分)
- AC日记——Dylans loves tree hdu 5274
- hdu_5274_Dylans loves tree(树剖)
- hdu 5274 Dylans loves tree(LCA + 线段树)
- HDU 5274 Dylans loves tree 树链剖分+线段树
- hdu_5274_Dylans loves tree(树剖)
- hdu 5274 Dylans loves tree && BestCoder Round #45
- hdu 5274 Dylans loves tree
- HDU5274 Dylans loves tree(树链剖分线段树)
- HDOJ 5274 Dylans loves tree
- HDU5274 Dylans loves tree(树链剖分+异或)
- 【线段树】 HDOJ 5274 Dylans loves tree
- hdu5274 - Dylans loves tree(树链剖分)