bzoj1984 月下“毛景树”(边权的树链剖分)
2017-09-08 17:30
405 查看
树链剖分,挺裸的,给的是边权,我们把边权都记在儿子上。用线段树维护单点修改,区间修改,区间加,区间最大值。需要注意的是对路径(x,y)进行操作时,不应算lca(x,y)这一点。因为他所代表的边不在路径上。
#include 4000 <bits/stdc++.h> using namespace std; #define ll long long #define inf 0x3f3f3f3f #define N 100010 inline 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; } int n,a ,p ,w ,h ,dep ,fa ,son ,size ,top ,id ,dfn=0; struct edge{ int to,next,val; }data[N<<1]; struct node{ int mx,add,cov; }tree[N<<2]; void dfs1(int x){ size[x]=1; for(int i=h[x];i;i=data[i].next){ int y=data[i].to; if(fa[x]==y) continue; fa[y]=x;dep[y]=dep[x]+1;p[i>>1]=y;a[y]=data[i].val; dfs1(y);size[x]+=size[y]; if(size[y]>size[son[x]]) son[x]=y; } } void dfs2(int x,int tp){ id[x]=++dfn;top[x]=tp;w[dfn]=a[x]; if(son[x]) dfs2(son[x],tp); for(int i=h[x];i;i=data[i].next){ int y=data[i].to; if(y==fa[x]||y==son[x]) continue; dfs2(y,y); } } inline void pushup(int p){ tree[p].mx=max(tree[p<<1].mx,tree[p<<1|1].mx); } inline void pushdown(int p){ if(!tree[p].cov&&!tree[p].add) return; if(tree[p].cov){ tree[p<<1].cov=tree[p<<1|1].cov=tree[p].cov; tree[p<<1].mx=tree[p<<1|1].mx=tree[p].cov; tree[p<<1].add=tree[p<<1|1].add=0; tree[p].cov=0; } if(tree[p].add){ tree[p<<1].add+=tree[p].add;tree[p<<1|1].add+=tree[p].add; tree[p<<1].mx+=tree[p].add;tree[p<<1|1].mx+=tree[p].add; tree[p].add=0; } } void build(int p,int l,int r){ if(l==r){tree[p].mx=w[l];return;} int mid=l+r>>1; build(p<<1,l,mid);build(p<<1|1,mid+1,r); pushup(p); } void change(int p,int l,int r,int x,int y,int val){ if(x<=l&&r<=y){ tree[p].cov=val;tree[p].mx=val; tree[p].add=0;return; } int mid=l+r>>1;pushdown(p); if(x<=mid) change(p<<1,l,mid,x,y,val); if(y>mid) change(p<<1|1,mid+1,r,x,y,val); pushup(p); } void add1(int p,int l,int r,int x,int y,int val){ if(x<=l&&r<=y){ tree[p].add+=val;tree[p].mx+=val;return; } int mid=l+r>>1;pushdown(p); if(x<=mid) add1(p<<1,l,mid,x,y,val); if(y>mid) add1(p<<1|1,mid+1,r,x,y,val); pushup(p); } int qmax(int p,int l,int r,int x,int y){ if(x<=l&&r<=y){return tree[p].mx;} int mid=l+r>>1,res=0;pushdown(p); if(x<=mid) res=max(res,qmax(p<<1,l,mid,x,y)); if(y>mid) res=max(res,qmax(p<<1|1,mid+1,r,x,y)); return res; } void dochange(int x,int y,int val){ while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); change(1,1,n,id[top[x]],id[x],val); x=fa[top[x]]; } if(id[x]>id[y]) swap(x,y);if(id[x]==id[y]) return; change(1,1,n,id[x]+1,id[y],val); } void doadd(int x,int y,int val){ while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); add1(1,1,n,id[top[x]],id[x],val); x=fa[top[x]]; } if(id[x]>id[y]) swap(x,y);if(id[x]==id[y]) return; add1(1,1,n,id[x]+1,id[y],val); } int domax(int x,int y){ int res=0; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); res=max(res,qmax(1,1,n,id[top[x]],id[x])); x=fa[top[x]]; } if(id[x]>id[y]) swap(x,y);if(id[x]==id[y]) return res; return max(res,qmax(1,1,n,id[x]+1,id[y])); } int main(){ // freopen("a.in","r",stdin); n=read(); for(int i=1;i<n;++i){ int x=read(),y=read(),v=read(); data[i<<1].to=y;data[i<<1].next=h[x];h[x]=i<<1;data[i<<1].val=v; data[i<<1|1].to=x;data[i<<1|1].next=h[y];h[y]=i<<1|1;data[i<<1|1].val=v; } dep[1]=1;dfs1(1);dfs2(1,1);build(1,1,n); while(1){ char op[10];scanf("%s",op+1); if(op[2]=='t') break;int x=read(),y=read(); if(op[2]=='h') change(1,1,n,id[p[x]],id[p[x]],y); if(op[2]=='o') dochange(x,y,read()); if(op[2]=='d') doadd(x,y,read()); if(op[2]=='a') printf("%d\n",domax(x,y)); } return 0; }
相关文章推荐
- bzoj1984 月下“毛景树”树链剖分 线段树
- [BZOJ1984] 月下“毛景树”|树链剖分|线段树
- [BZOJ1984]月下“毛景树”(树链剖分)
- 【树链剖分】【分块】【最近公共祖先】【块状树】bzoj1984 月下“毛景树”
- BZOJ 1984: 月下“毛景树” [树链剖分 边权]
- BZOJ 1984: 月下“毛景树”( 树链剖分 )
- Bzoj 1984: 月下“毛景树” 树链剖分
- [bzoj1984]月下“毛景树” 树链剖分
- 【BZOJ1984】月下“毛景树”-树链剖分
- BZOJ 1984 月下“毛景树” 树链剖分
- [BZOJ1984]月下“毛景树”(树链剖分)
- bzoj 1984: 月下“毛景树” (树链剖分)
- 【BZOJ1984】月下“毛景树” 树链剖分+线段树
- 【BZOJ-1984】月下“毛景树” 树链剖分
- 【bzoj1984】【坑】月下“毛景树” 树链剖分
- [BZOJ1984]月下“毛景树”解题报告|树链剖分
- 【bzoj1984】月下“毛景树” 树链剖分+线段树
- bzoj 1984: 月下“毛景树” 线段树+树链剖分
- 【BZOJ】【P1984】【月下“毛景树”】【题解】【链剖线段树】
- [BZOJ1984] 月下“毛景树”