POJ 3237:Tree
Tree Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 10224 Accepted: 2651 Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edges are numbered 1 through N − 1. Each edge is associated with a weight. Then you are to execute a series of instructions on the tree. The instructions can be one of the following forms: CHANGE i v Change the weight of the ith edge to v NEGATE a b Negate the weight of every edge on the path from a to b QUERY a b Find the maximum weight of edges on the path from a to b Input The input contains multiple test cases. The first line of input contains an integer t (t ≤ 20), the number of test cases. Then follow the test cases. Each test case is preceded by an empty line. The first nonempty line of its contains N (N ≤ 10,000). The next N − 1 lines each contains three integers a, b and c, describing an edge connecting nodes a and b with weight c. The edges are numbered in the order they appear in the input. Below them are the instructions, each sticking to the specification above. A lines with the word “DONE” ends the test case. Output For each “QUERY” instruction, output the result on a separate line. Sample Input 1 3 1 2 1 2 3 2 QUERY 1 2 CHANGE 1 3 QUERY 1 2 DONE Sample Output 1 3
芒果君:比较裸的树剖,然而我调了一下午……总共三个操作:修改单边权、查询路径上所有路的最大值或所有路的权值取相反数。第三个最难搞,因为本来维护好的最大值会变成最小值,那再维护下最小值不就完了……思路简单的不行然而代码量太大堪比线段树练习5 QAQ 注意中间的ret是负无穷!我简直要调到死了
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<map> 5 #define maxn 100010 6 #define inf 1<<29 7 using namespace std; 8 int top[maxn],deep[maxn],size[maxn],head[maxn],son[maxn],fa[maxn],dfn[maxn],tot,cnt,hl[maxn],n,q,lazy[maxn]; 9 char s[10]; 10 struct Edge{ 11 int u,v,w,ne; 12 }e[maxn<<1]; 13 struct Tree{ 14 int mi,ma; 15 }tree[maxn<<2]; 16 void init() 17 { 18 cnt=tot=0; 19 memset(tree,0,sizeof(tree)); 20 memset(top,0,sizeof(top)); 21 memset(deep,0,sizeof(deep)); 22 memset(size,0,sizeof(size)); 23 memset(head,0,sizeof(head)); 24 memset(son,0,sizeof(son)); 25 memset(fa,0,sizeof(fa)); 26 memset(dfn,0,sizeof(dfn)); 27 memset(hl,0,sizeof(hl)); 28 memset(lazy,0,sizeof(lazy)); 29 } 30 void add(int u,int v,int w) 31 { 32 e[++cnt].u=u; 33 e[cnt].v=v; 34 e[cnt].w=w; 35 e[cnt].ne=hl[u]; 36 hl[u]=cnt; 37 } 38 void dfs1(int x) 39 { 40 size[x]=1; 41 for(int i=hl[x];i;i=e[i].ne){ 42 int v=e[i].v; 43 if(v==fa[x]) continue; 44 deep[v]=deep[x]+1; 45 fa[v]=x; 46 dfs1(v); 47 size[x]+=size[v]; 48 if(size[v]>size[son[x]]) son[x]=v; 49 } 50 } 51 void dfs2(int x,int tp) 52 { 53 top[x]=tp; 54 dfn[x]=++tot; 55 if(son[x]) dfs2(son[x],tp); 56 for(int i=hl[x];i;i=e[i].ne){ 57 int v=e[i].v; 58 if(v==son[x]||v==fa[x]) continue; 59 dfs2(v,v); 60 } 61 } 62 void pushup(int o) 63 { 64 tree[o].ma=max(tree[o<<1].ma,tree[o<<1|1].ma); 65 tree[o].mi=min(tree[o<<1].mi,tree[o<<1|1].mi); 66 } 67 void pushdown(int o,int l,int r) 68 { 69 if(l==r||!lazy[o]) return; 70 lazy[o]=0; 71 lazy[o<<1]^=1,lazy[o<<1|1]^=1; 72 swap(tree[o<<1].mi,tree[o<<1].ma); 73 tree[o<<1].mi*=-1,tree[o<<1].ma*=-1; 74 swap(tree[o<<1|1].mi,tree[o<<1|1].ma); 75 tree[o<<1|1].mi*=-1,tree[o<<1|1].ma*=-1; 76 } 77 void update(int o,int l,int r,int x,int val) 78 { 79 if(l==r){ 80 tree[o].ma=tree[o].mi=val; 81 lazy[o]=0; 82 return; 83 } 84 pushdown(o,l,r); 85 int mid=(l+r)>>1; 86 if(x<=mid) update(o<<1,l,mid,x,val); 87 else update(o<<1|1,mid+1,r,x,val); 88 pushup(o); 89 } 90 int query(int o,int l,int r,int ql,int qr) 91 { 92 if(l>=ql&&r<=qr) return tree[o].ma; 93 pushdown(o,l,r); 94 int ret=-inf; 95 int mid=(l+r)>>1; 96 if(ql<=mid) ret=max(ret,query(o<<1,l,mid,ql,qr)); 97 if(qr>mid) ret=max(ret,query(o<<1|1,mid+1,r,ql,qr)); 98 pushup(o); 99 return ret; 100 } 101 int getmax(int x,int y) 102 { 103 int fx=top[x],fy=top[y],ret=-inf; 104 while(fx!=fy){ 105 if(deep[fx]>deep[fy]){ 106 swap(x,y); 107 swap(fx,fy); 108 } 109 ret=max(ret,query(1,1,n,dfn[fy],dfn[y])); 110 y=fa[fy]; 111 fy=top[y]; 112 } 113 if(x==y) return ret; 114 if(deep[x]>deep[y]) swap(x,y); 115 return max(ret,query(1,1,n,dfn[son[x]],dfn[y])); 116 } 117 void rever(int o,int l,int r,int ql,int qr) 118 { 119 if(l>=ql&&r<=qr){ 120 lazy[o]^=1; 121 swap(tree[o].mi,tree[o].ma); 122 tree[o].mi*=-1,tree[o].ma*=-1; 123 return; 124 } 125 pushdown(o,l,r); 126 int mid=(l+r)>>1; 127 if(ql<=mid) rever(o<<1,l,mid,ql,qr); 128 if(qr>mid) rever(o<<1|1,mid+1,r,ql,qr); 129 pushup(o); 130 } 131 void Negate(int x,int y) 132 { 133 int fx=top[x],fy=top[y]; 134 while(fx!=fy){ 135 if(deep[fx]>deep[fy]){ 136 swap(x,y); 137 swap(fx,fy); 138 } 139 rever(1,1,n,dfn[fy],dfn[y]); 140 y=fa[fy]; 141 fy=top[y]; 142 } 143 if(x==y) return; 144 if(deep[x]>deep[y]) swap(x,y); 145 rever(1,1,n,dfn[son[x]],dfn[y]); 146 } 147 int main() 148 { 149 int T,x,y,w; 150 scanf("%d",&T); 151 while(T--){ 152 init(); 153 scanf("%d",&n); 154 for(int i=1;i<n;++i){ 155 scanf("%d%d%d",&x,&y,&w); 156 add(x,y,w); 157 add(y,x,w); 158 } 159 dfs1(1); 160 dfs2(1,1); 161 for(int i=1;i<=2*n-2;i+=2){ 162 int u=e[i].u,v=e[i].v; 163 if(deep[u]>deep[v]) swap(u,v); 164 update(1,1,n,dfn[v],e[i].w); 165 } 166 while(scanf("%s",s)!=EOF){ 167 if(s[0]=='D') break; 168 scanf("%d%d",&x,&y); 169 if(s[0]=='N') Negate(x,y); 170 else if(s[0]=='C'){ 171 x=x*2-1; 172 int u=e[x].u,v=e[x].v; 173 if(deep[u]>deep[v]) swap(u,v); 174 update(1,1,n,dfn[v],y); 175 } 176 else printf("%d\n",getmax(x,y)); 177 } 178 179 } 180 return 0; 181 }