Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions: 12247 | Accepted: 3151 |
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
Source
题意就是: 有T组数据 ,给你n个点的树,有三种操作:
1.CHANGE i v :将第i条边的值改为v
2.NEGATE a b :将a点到b点路径上的边权取反
3.QUERY a b :查询a点到b点路径上最大的边权值,
由于有取反操作,记录最大和最小值 然后取反并交换就可以,用线段树来维护。
一开始打死都不想用结构体版的,最后发现结构体版的好像写起来简洁一些,真香警告。。。
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<bitset> 6 #include<cassert> 7 #include<cctype> 8 #include<cmath> 9 #include<cstdlib> 10 #include<ctime> 11 #include<deque> 12 #include<iomanip> 13 #include<list> 14 #include<map> 15 #include<queue> 16 #include<set> 17 #include<stack> 18 #include<vector> 19 using namespace std; 20 typedef long long ll; 21 22 const double PI=acos(-1.0); 23 const double eps=1e-6; 24 const ll mod=1e9+7; 25 const int inf=0x3f3f3f3f; 26 const int maxn=2e5+10; 27 const int maxm=100+10; 28 #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); 29 #define lson t<<1,l,mid 30 #define rson t<<1|1,mid+1,r 31 32 33 34 int eg[maxn][3]; 35 int head[maxn],cnt; 36 37 struct Edge{ 38 int to,next; 39 }edge[maxn<<1]; 40 41 void add(int u,int v) 42 { 43 edge[cnt].to=v; 44 edge[cnt].next=head[u]; 45 head[u]=cnt++; 46 } 47 48 int num; 49 int val[maxn],siz[maxn],dep[maxn],son[maxn]; 50 int top[maxn],tid[maxn],pos[maxn],fa[maxn]; 51 52 void init() 53 { 54 memset(head,-1,sizeof(head)); 55 memset(son,-1,sizeof(son)); 56 cnt=num=0; 57 } 58 59 ///树链剖分部分 60 void dfs1(int u,int father,int d) 61 { 62 dep[u]=d; 63 fa[u]=father; 64 siz[u]=1; 65 for(int i=head[u];~i;i=edge[i].next) 66 { 67 int v=edge[i].to; 68 if(v!=father) 69 { 70 dfs1(v,u,d+1); 71 siz[u]+=siz[v]; 72 if(son[u]==-1||siz[v]>siz[son[u]]) 73 son[u]=v; 74 } 75 } 76 } 77 78 void dfs2(int u,int tp) 79 { 80 top[u]=tp; 81 tid[u]=++num; 82 pos[tid[u]]=u; 83 if(son[u]==-1) return ; 84 dfs2(son[u],tp); 85 for(int i=head[u];~i;i=edge[i].next) 86 { 87 int v=edge[i].to; 88 if(v!=son[u]&&v!=fa[u]) 89 dfs2(v,v); 90 } 91 } 92 93 ///线段树部分 94 struct Node{ 95 int l,r,mx,mn,lazy; 96 }node[maxn<<2]; 97 98 void Swap(int &x,int &y){int t=x;x=-y;y=-t;} 99 100 void pushup(int t) 101 { 102 node[t].mx=max(node[t<<1].mx,node[t<<1|1].mx); 103 node[t].mn=min(node[t<<1].mn,node[t<<1|1].mn); 104 } 105 106 void pushdown(int t) 107 { 108 if(node[t].lazy) 109 { 110 int tmp=node[t].lazy; 111 node[t<<1].lazy+=tmp; 112 node[t<<1|1].lazy+=tmp; 113 ///注意这里,两个子区间是否取反是依靠当前区间的懒惰标记判断的 114 if(tmp&1) 115 { 116 Swap(node[t<<1].mx,node[t<<1].mn); 117 Swap(node[t<<1|1].mx,node[t<<1|1].mn); 118 } 119 node[t].lazy=0; 120 } 121 } 122 123 void build(int t,int l,int r) 124 { 125 node[t].l=l; 126 node[t].r=r; 127 node[t].lazy=0; 128 if(l==r) 129 { 130 node[t].mx=node[t].mn=0; 131 return ; 132 } 133 134 int mid=(l+r)>>1; 135 build(lson); 136 build(rson); 137 pushup(t); 138 } 139 140 void update(int t,int ind,int v) 141 { 142 if(node[t].l==node[t].r&&node[t].l==ind) 143 { 144 node[t].mx=v; 145 node[t].mn=v; 146 node[t].lazy=0; 147 return ; 148 } 149 150 pushdown(t); 151 int mid=(node[t].l+node[t].r)>>1; 152 if(ind<=mid) update(t<<1,ind,v); 153 else update(t<<1|1,ind,v); 154 pushup(t); 155 } 156 157 void Negate(int t,int l,int r) 158 { 159 if(node[t].l>=l&&node[t].r<=r) 160 { 161 node[t].lazy++; 162 Swap(node[t].mx,node[t].mn);//这里要马上取反 163 return ; 164 } 165 166 pushdown(t); 167 int mid=(node[t].l+node[t].r)>>1; 168 if(l<=mid) Negate(t<<1,l,r); 169 if(r> mid) Negate(t<<1|1,l,r); 170 pushup(t); 171 } 172 173 int query(int t,int l,int r) 174 { 175 if(node[t].l>=l&&node[t].r<=r) 176 { 177 return node[t].mx; 178 } 179 180 pushdown(t); 181 int ret=-inf; 182 int mid=(node[t].l+node[t].r)>>1; 183 if(l<=mid) ret=max(ret,query(t<<1,l,r)); 184 if(r> mid) ret=max(ret,query(t<<1|1,l,r)); 185 pushup(t); 186 return ret; 187 } 188 189 int solveMax(int x,int y) 190 { 191 int ret=-inf; 192 while(top[x]!=top[y]) 193 { 194 if(dep[top[x]]<dep[top[y]]) swap(x,y); 195 ret=max(ret,query(1,tid[top[x]],tid[x])); 196 x=fa[top[x]]; 197 } 198 199 if(x==y) return ret; 200 if(dep[x]>dep[y]) swap(x,y); 201 return max(ret,query(1,tid[son[x]],tid[y])); 202 } 203 204 void change(int x,int y) 205 { 206 while(top[x]!=top[y]) 207 { 208 if(dep[top[x]]<dep[top[y]]) swap(x,y); 209 Negate(1,tid[top[x]],tid[x]); 210 x=fa[top[x]]; 211 } 212 213 if(x==y) return ; 214 if(dep[x]>dep[y]) swap(x,y); 215 Negate(1,tid[son[x]],tid[y]); 216 } 217 218 int main() 219 { 220 char ope[10]; 221 int T,n;scanf("%d",&T); 222 while(T--) 223 { 224 scanf("%d",&n); 225 init(); 226 for(int i=1;i<n;i++) 227 { 228 scanf("%d%d%d",&eg[i][0],&eg[i][1],&eg[i][2]); 229 add(eg[i][0],eg[i][1]); 230 add(eg[i][1],eg[i][0]); 231 } 232 dfs1(1,0,0); 233 dfs2(1,1); 234 build(1,1,n); 235 for(int i=1;i<n;i++) 236 { 237 if(dep[eg[i][0]]<dep[eg[i][1]]) swap(eg[i][0],eg[i][1]); 238 update(1,tid[eg[i][0]],eg[i][2]); 239 } 240 int a,b; 241 while(scanf("%s",ope)&&ope[0]!='D') 242 { 243 scanf("%d%d",&a,&b); 244 if(ope[0]=='Q') 245 { 246 printf("%d\n",solveMax(a,b)); 247 } 248 if(ope[0]=='C') 249 { 250 update(1,tid[eg[a][0]],b); 251 } 252 if(ope[0]=='N') 253 { 254 change(a,b); 255 } 256 } 257 } 258 }