1607:do you have the Template? Time Limit: 7 Sec Memory Limit: MB
Submit: Solved: 8
[Submit] [Status] [Web Board] Description
There is a tree with N vertices and each edges has a positive length.
And here comes 4 operations,
0 A B, means query the maximum length and the sum of length on the path between vertex A and vertex b.
1 A B, means change the a-th edge ' s length to B.
2 A B 0 C, means edges ' length on the path between vertex A and vertex B to C.
2 A B 1 C, means add all edges ' length to the path between vertex A and vertex B by C.
Input
There ' re several cases.
The first line contains a positive an integer N (2 <= n <= 10000), meaning there ' re N vertices, marked 1 to N. Then n–1 lines follow and the i-th line describing the i-th edge. Each line contains three integers a b c, meaning there are an edge between vertex A and vertex B with the length of C.
Then one integer m (M <= 10000), means there ' re M queries. and followed by M-lines, each line would contain one operation described as above.
Output
For each 0 A-B query, you should output the maximum length and the sum.
The data insure no number would be bigger than 2^31.
Sample Input
41 2 12 3 22 4 3100 1 30 1 40 3 41 2 30 1 32 4 3 0 20 1 42 4 3 1 20 1 30 1 4
Sample Output
2 33 43 53 42 34 54 5
Test instructions: Given a tree has n nodes, each side has a value, and now has m operations:
0 A B indicates the maximum and edge tree sum of the path of the output from point A to point B.
1 A B means that the weight of the edge of article A is changed to B.
2 a B 0 C means that each edge of the path from point A to point B becomes C
2 A B 1 C indicates the each edge of the path of point A to B is added C
Pit point: This problem of the CSU is built with vectors on WA. There is a loophole in the standard code, which is to use ROOT[K].TOC to determine whether to update the left and right child nodes of K in the segment tree.
Problem solving: Using a tree chain to split. Use a line segment tree to maintain edge rights.
#include <stdio.h> #include <string.h> #include <vector>const int n=10015;using namespace STD; int Head[n], to[n << 1], next1[n << 1], tot;int top[n]; Top[v]=u indicates that the point v,u is in a chain and U is the point with the lowest depth of the chain (that is, the top) int fath[n]; Record parent node int deep[n]; Depth of each point on the tree int num[n]; Number of nodes per subtrees tree int son[n]; Selected heavy Edge sub-node int p[n]; Each point in the tree corresponds to the point int pos in the segment tree; void Addedge (const int& u, const int& v) {To[tot] = V, next1[tot] = Head[u], head[u] = tot++;} void Addundiredge (const int& u, const int& v) {Addedge (U, v), Addedge (V, u);} void init (int n) {pos=0; tot=0; memset (son,-1,sizeof (son)); memset (head,-1,sizeof (Head));} void dfs1 (int u,int pre,int d) {deep[u]=d; fath[u]=pre; num[u]=1; for (int i = head[u]; i =-1; i = Next1[i]) {int v = to[i]; if (v==pre) continue; DFS1 (v,u,d+1); NUM[U]+=NUM[V]; if (son[u]==-1| | Num[v]>num[son[u]]) son[u]=v; }}void GetPos (int u,int root) {top[u]=root; p[u]=pos++; if (son[u]==-1) return; GetPos (Son[u],root); for (int i = head[u]; i =-1; i = Next1[i]) {int v = to[i]; if (Son[u]!=v&&v!=fath[u]) GetPos (V,V); }}//segment tree struct tree{int sum,maxv,toc,addc;} Root[n*4];int val[n];int MAX (int a,int b) {return a>b?a:b;} void build (int l,int r,int k) {int mid= (L+R)/2; root[k].addc=0; root[k].toc=0; if (l==r) {root[k].sum=root[k].maxv=val[l]; return; } build (L,mid,k<<1); Build (mid+1,r,k<<1|1); root[k].sum=root[k<<1].sum+root[k<<1|1].sum; Root[k].maxv=max (ROOT[K<<1].MAXV,ROOT[K<<1|1].MAXV);} void Upson (int k,int l,int r) {int mid= (L+R)/2; if (ROOT[K].TOC) {root[k<<1].sum= (mid-l+1) *root[k].toc; root[k<<1].maxv=root[k].toc; root[k<<1].toc=root[k].toc; root[k<<1].addc=0; Root[k<<1|1].sum= (R-mid) *root[k].toc; root[k<<1|1].maxv=root[k].toc; Root[k<<1|1].toc=root[k].toc; root[k<<1|1].addc=0; root[k].toc=0; } if (ROOT[K].ADDC) {root[k<<1].sum+= (mid-l+1) *ROOT[K].ADDC; root[k<<1].maxv+=root[k].addc; root[k<<1].addc+=root[k].addc; root[k<<1|1].sum+= (R-mid) *ROOT[K].ADDC; root[k<<1|1].maxv+=root[k].addc; root[k<<1|1].addc+=root[k].addc; root[k].addc=0; }}void updata1 (int l,int r,int k,const int l,const int R,int c) {if (l<=l&&r<=r) {root[k].sum= ( r-l+1) *c; Root[k].maxv=c; Root[k].toc=c; root[k].addc=0; return; } int mid= (L+R)/2; Upson (K,L,R); if (l<=mid) updata1 (L,MID,K<<1,L,R,C); if (mid<r) updata1 (MID+1,R,K<<1|1,L,R,C); root[k].sum=root[k<<1].sum+root[k<<1|1].sum; Root[k].maxv=max (ROOT[K<<1].MAXV,ROOT[K<<1|1].MAXV);} void updata2 (int l,int r,int k, int l, int r,int c) {if (l<=l&&r<=r) { root[k].sum+= (r-l+1) *c; Root[k].maxv+=c; Root[k].addc+=c; return; } int mid= (L+R)/2; Upson (K,L,R); if (l<=mid) updata2 (L,MID,K<<1,L,R,C); if (mid<r) updata2 (MID+1,R,K<<1|1,L,R,C); root[k].sum=root[k<<1].sum+root[k<<1|1].sum; Root[k].maxv=max (ROOT[K<<1].MAXV,ROOT[K<<1|1].MAXV);} int sum,maxv;void query (int l,int r,int k,int l,int R) {if (l<=l&&r<=r) {sum+=root[k].sum; Maxv=max (MAXV,ROOT[K].MAXV); return; } int mid= (L+R)/2; Upson (K,L,R); if (l<=mid) query (L,MID,K<<1,L,R); if (mid<r) query (MID+1,R,K<<1|1,L,R);} void SWP (int &a,int &b) {int TT; Tt=a; A=b; B=tt;} void Operat0 (int u,int v) {int f1=top[u], f2=top[v]; sum=0; maxv=0; while (F1!=F2) {if (Deep[f1]<deep[f2]) {SWP (F1,F2); SWP (U,V); } query (1,pos,1,p[f1],p[u]); U=FATH[F1]; f1=top[U]; } if (u==v) return; if (Deep[u]>deep[v]) SWP (U,V); Query (1,pos,1,p[son[u]],p[v]);} void Operat1 (int u,int v,int c) {int f1=top[u], f2=top[v]; while (F1!=F2) {if (Deep[f1]<deep[f2]) {SWP (F1,F2); SWP (U,V); } updata1 (1,pos,1,p[f1],p[u],c); U=FATH[F1]; F1=top[u]; } if (u==v) return; if (Deep[u]>deep[v]) SWP (U,V); Updata1 (1,pos,1,p[son[u]],p[v],c);} void Operat2 (int u,int v,int c) {int f1=top[u], f2=top[v]; while (F1!=F2) {if (Deep[f1]<deep[f2]) {SWP (F1,F2); SWP (U,V); } updata2 (1,pos,1,p[f1],p[u],c); U=FATH[F1]; F1=top[u]; } if (u==v) return; if (Deep[u]>deep[v]) SWP (U,V); Updata2 (1,pos,1,p[son[u]],p[v],c);} struct edg{int u,v,c;} Edg[n];int Main () {int n,q,op,a,b; while (scanf ("%d", &n)!=eof) {init (n); for (int i=1;i<n;i++) {scanf ("%d%d%d", &edg[i].u,&edg[i].v,&edg[i].c); Addundiredge (edg[i].u, EDG[I].V); } DFS1 (1,1,1); GetPos (a); Pos=n; for (int i=1;i<n;i++) {if (deep[edg[i].u]>deep[edg[i].v]) edg[i].v=edg[i].u; VAL[P[EDG[I].V]]=EDG[I].C; } build (1,pos,1); scanf ("%d", &q); while (q--) {scanf ("%d%d%d", &op,&a,&b); if (op==0) {Operat0 (A, b); printf ("%d%d\n", maxv,sum); } else if (op==1) updata1 (1,pos,1,p[edg[a].v],p[edg[a].v],b); else {int tt,c; scanf ("%d%d", &tt,&c); if (tt==0) OPERAT1 (A,B,C); else Operat2 (A,B,C); }}}}/************************************************************** problem:1607 user:aking2015 La Nguage:c++ result:accepted time:912 ms memory:2180 kb****************************************************************/
CSU 1607:do You have the Template? (tree chain split)