poj 3237 Tree 树链剖分+lazy标记
来源:互联网 发布:手机淘宝历史版本5.1.1 编辑:程序博客网 时间:2024/05/21 22:44
比较麻烦的树链剖分,其中Neg表示a、b之间所有数取相反数,可以用lazy标记处理,由于代码量略大注意别手残。
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#define maxn 100005#define inf 0x3fffffffusing namespace std;int dep[maxn],top[maxn],id[maxn],son[maxn],size[maxn],num,fa[maxn],tot,head[maxn];struct pppi{ int to; int next;}pp2[2*maxn];struct ppi{ int f; int t; int co;}pp1[maxn];struct pi{ int le; int ri; int lazy; int max; int min;}pp[4*maxn];void add(int u,int v){ pp2[tot].to=v; pp2[tot].next=head[u]; head[u]=tot++; pp2[tot].to=u; pp2[tot].next=head[v]; head[v]=tot++;}void build(int tot,int l,int r){ pp[tot].le=l; pp[tot].ri=r; pp[tot].lazy=0; pp[tot].max=-inf; pp[tot].min=inf; if(l==r) return ; build(2*tot,l,(l+r)/2); build(2*tot+1,(l+r)/2+1,r);}int q1(int tot,int l,int r){ if(pp[tot].le>=l&&pp[tot].ri<=r) return pp[tot].lazy; int s=0; s+=pp[tot].lazy; int mid=(pp[tot].le+pp[tot].ri)/2; if(l<=mid) s+=q1(2*tot,l,r); if(r>mid) s+=q1(2*tot+1,l,r); return s;}void push(int tot){ int x1,y1,x2,y2; if(pp[2*tot].lazy%2==0){ x1=pp[2*tot].max; x2=pp[2*tot].min; } else{ x1=-pp[2*tot].min; x2=-pp[2*tot].max; } if(pp[2*tot+1].lazy%2==0){ y1=pp[2*tot+1].max; y2=pp[2*tot+1].min; } else{ y1=-pp[2*tot+1].min; y2=-pp[2*tot+1].max; } pp[tot].max=max(x1,y1); pp[tot].min=min(x2,y2);}void merg(int tot,int x,int p){ if(pp[tot].le==pp[tot].ri){ pp[tot].max=p; pp[tot].min=p; return ; } int mid=(pp[tot].le+pp[tot].ri)/2; if(x<=mid) merg(2*tot,x,p); else merg(2*tot+1,x,p); push(tot);}void merg1(int tot,int l,int r){ if(pp[tot].le>=l&&pp[tot].ri<=r){ pp[tot].lazy++; return ; } int mid=(pp[tot].le+pp[tot].ri)/2; if(l<=mid) merg1(2*tot,l,r); if(r>mid) merg1(2*tot+1,l,r); push(tot);}int query(int tot,int l,int r){ if(pp[tot].le>=l&&pp[tot].ri<=r){ if(q1(1,pp[tot].le,pp[tot].ri)%2==0) return pp[tot].max; return -pp[tot].min; } int s=-inf,mid=(pp[tot].le+pp[tot].ri)/2; if(l<=mid) s=max(s,query(2*tot,l,r)); if(r>mid) s=max(s,query(2*tot+1,l,r)); return s;}void dfs1(int u,int pa,int d){ dep[u]=d; size[u]=1; son[u]=0; fa[u]=pa; int k,v; k=head[u]; while(k!=-1){ v=pp2[k].to; if(v!=pa){ dfs1(v,u,d+1); size[u]+=size[v]; if(size[son[u]]<size[v]) son[u]=v; } k=pp2[k].next; }}void dfs2(int u,int pa,int tp){ top[u]=tp; id[u]=num++; if(son[u]) dfs2(son[u],u,tp); int k,v; k=head[u]; while(k!=-1){ v=pp2[k].to; if(v!=pa&&v!=son[u]){ dfs2(v,u,v); } k=pp2[k].next; }}void update(int u,int v){ int to1,to2; to1=top[u]; to2=top[v]; while(to1!=to2){ if(dep[to1]<dep[to2]||(dep[to1]==dep[to2]&&u<v)){ swap(to1,to2); swap(u,v); } if(!(u==to1&&u==1)) merg1(1,id[to1],id[u]); u=fa[to1]; to1=top[u]; } if(u==v) return ; if(dep[u]>dep[v]) swap(u,v); merg1(1,id[u]+1,id[v]);}int get(int u,int v){ int to1,to2,s; s=-inf; to1=top[u]; to2=top[v]; while(to1!=to2){ if(dep[to1]<dep[to2]){ swap(to1,to2); swap(u,v); } s=max(s,query(1,id[to1],id[u])); u=fa[to1]; to1=top[u]; } if(u==v) return s; if(dep[u]>dep[v]) swap(u,v); s=max(s,query(1,id[u]+1,id[v])); return s;}char c[20];int main(){ int t,n,i,p,k; cin>>t; while(t--){ scanf("%d",&n); memset(head,-1,sizeof(head)); tot=0; num=0; build(1,1,n-1); for(i=1;i<n;i++){ scanf("%d%d%d",&pp1[i].f,&pp1[i].t,&pp1[i].co); add(pp1[i].f,pp1[i].t); } dfs1(1,1,1); dfs2(1,1,1); for(i=1;i<n;i++){ if(fa[pp1[i].t]==pp1[i].f) merg(1,id[pp1[i].t],pp1[i].co); else merg(1,id[pp1[i].f],pp1[i].co); } while(1){ scanf("%s",c); if(c[0]=='D') break; if(c[0]=='Q'){ scanf("%d%d",&p,&k); if(p==k){ printf("0\n"); continue; } printf("%d\n",get(p,k)); } else if(c[0]=='C'){ scanf("%d%d",&p,&k); if(fa[pp1[p].f]==pp1[p].t){ if(q1(1,id[pp1[p].f],id[pp1[p].f])%2==0) merg(1,id[pp1[p].f],k); else merg(1,id[pp1[p].f],-k); } else{ if(q1(1,id[pp1[p].t],id[pp1[p].t])%2==0) merg(1,id[pp1[p].t],k); else merg(1,id[pp1[p].t],-k); } } else if(c[0]=='N'){ scanf("%d%d",&p,&k); update(p,k); } } }}
0 0
- poj 3237 Tree 树链剖分+lazy标记
- POJ 3468 Lazy标记
- POJ 3237 Tree(树链剖分 线段树区间标记)
- poj 3225 线段树注意lazy标记
- POJ 3468 线段树+lazy标记
- POJ 3225 线段树+lazy标记
- poj 3468 线段树 lazy标记模板
- poj-2777 线段树lazy标记+位运算
- POJ 2777 Count Color 线段树 + lazy标记
- POJ 2777 count color(线段树,lazy标记)
- POJ 3667 Hotel 线段树lazy标记 (模板~~)
- poj3468(lazy标记)
- 线段树lazy标记
- poj 3237 树链剖分模板(用到线段树lazy操作)
- POJ 3237 Tree 树链剖分
- 【POJ】3237 Tree 树链剖分
- POJ 3237 Tree 树链剖分
- 【树链剖分】 POJ 3237 Tree
- Uninstall Java in Mac mavericks(plus)
- Eclipse一闪而过
- = Day 1 = 《The first english diary》
- ios 数据存储的几种方式
- leetcode valid sudoku c++
- poj 3237 Tree 树链剖分+lazy标记
- 快速排序
- 死锁的相关概念
- quick 中使用命令创建工程(没有验证) (windows 7)
- 快速排序2
- gh0st源码阅读--监控代码
- The Euler function
- 互联网数据响应时间计算公式
- jsp操作Access