标签:
Description
You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edges are numbered 1 throughN − 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
ivChange the weight of the ith edge to v NEGATE
abNegate the weight of every edge on the path from a to b QUERY
abFind 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 DONESample Output
1 3
【题意】
指定一颗树上有3个操作:
询问操作,询问a点和b点之间的路径上最长的那条边的长度;
取反操作,将a点和b点之间的路径权值都取相反数;
变化操作,把某条边的权值x变成指定的值。
【分析】
人生第一道树剖题,调了好久啊,200+的代码还打了对拍= =
就是裸的树链剖分+线段树啦。
就是线段树打得不够熟练所以调了那么久,lazy标记不大会用~~
树剖的主要过程就是两次的dfs,第一次求fa,第二次求top。询问过程就是一直跳,跳到两个东西在一条重链上去。
因为某种特殊性质,所以他很快。。
代码如下:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 #define Maxn 10010 8 #define INF 100000000 9 10 int fa[Maxn],first[Maxn],size[Maxn],dep[Maxn],son[Maxn]; 11 int w[Maxn],top[Maxn];int wl; 12 int b[Maxn][5]; 13 14 struct node 15 { 16 int x,y,c,next; 17 }t[2*Maxn];int len; 18 19 struct nnode 20 { 21 int l,r,lc,rc,mx,mn; 22 bool lazy; 23 }tr[2*Maxn];int tl; 24 25 int mymax(int x,int y) {return x>y?x:y;} 26 int mymin(int x,int y) {return x<y?x:y;} 27 28 void ins(int x,int y,int c) 29 { 30 t[++len].x=x;t[len].y=y;t[len].c=c; 31 t[len].next=first[x];first[x]=len; 32 } 33 34 void dfs1(int x,int f) 35 { 36 fa[x]=f;dep[x]=dep[f]+1;size[x]=1; 37 son[x]=0; 38 for(int i=first[x];i;i=t[i].next) if(t[i].y!=f) 39 { 40 dfs1(t[i].y,x); 41 size[x]+=size[t[i].y]; 42 if(size[t[i].y]>size[son[x]]) son[x]=t[i].y; 43 } 44 } 45 46 void dfs2(int x,int tp) 47 { 48 w[x]=++wl; 49 top[x]=tp; 50 if(size[x]!=1) dfs2(son[x],tp); 51 for(int i=first[x];i;i=t[i].next) if(t[i].y!=fa[x]&&t[i].y!=son[x]) 52 { 53 dfs2(t[i].y,t[i].y); 54 } 55 } 56 57 int build(int l,int r) 58 { 59 int x=++tl; 60 tr[x].l=l;tr[x].r=r;tr[x].mx=-INF;tr[x].mn=INF;tr[x].lazy=0; 61 if(l!=r) 62 { 63 int mid=(l+r)>>1; 64 tr[x].lc=build(l,mid); 65 tr[x].rc=build(mid+1,r); 66 } 67 return x; 68 } 69 70 void upd(int x) 71 { 72 if(!tr[x].lazy) return; 73 tr[x].lazy=0; 74 int a=tr[x].mx; 75 tr[x].mx=-tr[x].mn;tr[x].mn=-a; 76 if(tr[x].l==tr[x].r) return; 77 tr[tr[x].lc].lazy=!tr[tr[x].lc].lazy; 78 tr[tr[x].rc].lazy=!tr[tr[x].rc].lazy; 79 } 80 81 void change(int x,int y,int c) 82 { 83 upd(x); 84 if(tr[x].l==tr[x].r) 85 { 86 tr[x].mx=c; 87 tr[x].mn=c; 88 return; 89 } 90 int mid=(tr[x].l+tr[x].r)>>1; 91 if(y<=mid) change(tr[x].lc,y,c); 92 else change(tr[x].rc,y,c); 93 upd(tr[x].lc);upd(tr[x].rc); 94 tr[x].mx=mymax(tr[tr[x].lc].mx,tr[tr[x].rc].mx); 95 tr[x].mn=mymin(tr[tr[x].lc].mn,tr[tr[x].rc].mn); 96 } 97 98 int qtree(int x,int l,int r) 99 { 100 upd(x); 101 if(tr[x].l==l&&tr[x].r==r) return tr[x].mx; 102 int mid=(tr[x].l+tr[x].r)>>1; 103 if(r<=mid) return qtree(tr[x].lc,l,r); 104 if(l>mid) return qtree(tr[x].rc,l,r); 105 return mymax(qtree(tr[x].lc,l,mid),qtree(tr[x].rc,mid+1,r)); 106 } 107 108 int query(int x,int y) 109 { 110 int tmp=-INF; 111 int f1=top[x],f2=top[y]; 112 while(f1!=f2) 113 { 114 if(dep[f1]<dep[f2]) 115 { 116 swap(f1,f2); 117 swap(x,y); 118 } 119 tmp=mymax(qtree(1,w[f1],w[x]),tmp); 120 x=fa[f1]; 121 f1=top[x]; 122 } 123 if(x==y) return tmp; 124 if(dep[x]<dep[y]) swap(x,y); 125 return mymax(tmp,qtree(1,w[son[y]],w[x])); 126 } 127 128 void change2(int x,int l,int r) 129 { 130 upd(x); 131 if(tr[x].l==l&&tr[x].r==r) 132 { 133 tr[x].lazy=!tr[x].lazy; 134 upd(x); 135 return; 136 } 137 int mid=(tr[x].l+tr[x].r)>>1; 138 if(r<=mid) change2(tr[x].lc,l,r); 139 else if(l>mid) change2(tr[x].rc,l,r); 140 else 141 { 142 change2(tr[x].lc,l,mid); 143 change2(tr[x].rc,mid+1,r); 144 } 145 upd(tr[x].lc);upd(tr[x].rc); 146 tr[x].mx=mymax(tr[tr[x].lc].mx,tr[tr[x].rc].mx); 147 tr[x].mn=mymin(tr[tr[x].lc].mn,tr[tr[x].rc].mn); 148 } 149 150 void negate1(int x,int y) 151 { 152 int f1=top[x],f2=top[y]; 153 while(f1!=f2) 154 { 155 if(dep[f1]<dep[f2]) 156 { 157 swap(f1,f2); 158 swap(x,y); 159 } 160 change2(1,w[f1],w[x]); 161 x=fa[f1]; 162 f1=top[x]; 163 } 164 if(x==y) return; 165 if(dep[x]<dep[y]) swap(x,y); 166 change2(1,w[son[y]],w[x]); 167 } 168 169 int main() 170 { 171 int T; 172 scanf("%d",&T); 173 while(T--) 174 { 175 int n; 176 scanf("%d",&n); 177 memset(first,0,sizeof(first)); 178 len=0; 179 for(int i=1;i<n;i++) 180 { 181 int x,y,c; 182 scanf("%d%d%d",&x,&y,&c); 183 b[i][0]=x;b[i][1]=y;b[i][2]=c; 184 ins(x,y,c);ins(y,x,c); 185 } 186 dep[0]=0;size[0]=0; 187 dfs1(1,0);wl=0; 188 dfs2(1,1); 189 char s[10]; 190 tl=0; 191 build(1,wl); 192 for(int i=1;i<n;i++) 193 { 194 if(dep[b[i][0]]<dep[b[i][1]]) swap(b[i][0],b[i][1]); 195 change(1,w[b[i][0]],b[i][2]); 196 } 197 while(1) 198 { 199 scanf("%s",s); 200 if(s[0]==‘D‘) break; 201 if(s[0]==‘Q‘) 202 { 203 int x,y; 204 scanf("%d%d",&x,&y); 205 printf("%d\n",query(x,y)); 206 } 207 else if(s[0]==‘C‘) 208 { 209 int x,y; 210 scanf("%d%d",&x,&y); 211 change(1,w[b[x][0]],y);//单点修改 212 } 213 else 214 { 215 int x,y; 216 scanf("%d%d",&x,&y); 217 negate1(x,y); 218 } 219 } 220 } 221 return 0; 222 }
2016-05-08 14:50:31
标签:
原文地址:http://www.cnblogs.com/Konjakmoyu/p/5470636.html