Description
S has N cities, numbered from 1 to N. The cities are connected by N-1 two-way roads, so that
all other cities can be reached from one city. Each city believes in different religions, such as flying noodle religion, invisible unicorn religion, and Jedi religion are all common beliefs. For convenience, we use different positive integers to represent various religions, and the residents of country S often travel. They always took the shortest route when traveling, and to avoid trouble, they only stayed in cities of the same faith as theirs. Of course, the end of the journey is also the city of the same faith as him. The government of S country has set a different travel rating for each city, and travelers often write down the sum or maximum rating of the cities they have stayed in on the way (including the origin and destination).
In the history of country S, the following events often occurred:
"CC xc": all residents of city x converted to c religion;
"CW xw": the rating of city x was adjusted to w;
"QS xy": a traveler A traveler starts from city x, goes to city y, and records the sum of the ratings of the cities where he stayed on the way;
"QM xy": A traveler starts from city x, goes to city y, and records the cities where he stays on the way
. rating maximum.
The numbers recorded by travelers have been lost due to age, but the beliefs and ratings of each city before the records began, as well as the event records themselves, are intact. Based on this information, restore the numbers the traveler wrote down. For convenience, we consider the intervals between events to be long enough that the ratings and beliefs of all cities remain the same on any given trip.
Input
The first line of input contains the integer N, and Q represents the number of cities and then the number of events.
Next N lines, the i+lth line, two integers Wi, Ci, in turn, represent the
rating and belief of city i before the recording starts.
The next N-1 lines each have two integers x, y representing a two-way road.
The next Q lines, one operation per line, are formatted as described above.
Output
For each QS and QM event, output a row representing the number recorded by the traveler.
Sample Input
3 1
2 3
1 2
3 3
5 1
1 2
1 3
3 4
3 5
QS 1 5
CC 3 1
QS 1 5
CW 3 3
QS 1 5
QM 2 4
Sample Output
9
11
3
HINT
N,Q < =10^5 , C < =10^5
The data guarantees that for all QS and QM events, the starting and ending cities have the same belief; at any time
, the city's rating is always a positive integer no greater than 10^4, and the religion value is no greater than C.
Because the board was copied from another question, the details were not changed. It took WA twice to pass QAQ.
For this question, our first reaction was: Hey, this is not a bare tree chain division...
Wait, it doesn't seem quite right for
this person who only counts the same kind of people on the chain and the starting point and the end point every time. In
that case, we can do a chain dissection for each kind...
Wait, it seems that it is still not quite right to
open the space. QAQ
, then let's open the line segment tree dynamically.
Analysis of a wave of complexity: Only the update function in my code needs to be dynamically opened. In the worst case of each update, log nodes will be added in the worst case . In
that case, the space is NlogN.
get it
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #define N (2000000+100) 5 using namespace std; 6 7 struct segt{int val,add,max,ls,rs;}Segt[N<<2],refun[N]; 8 struct node{int to,next;}edge[N<<1]; 9 int n,m,a[N],u,v,l,ans,w[N],c[N],Root[N],x,y; 10 int head[N],num_edge; 11 int Father[N],Depth[N],Son[N],Sum[N]; 12 int T_num[N],Tree[N],Top[N],dfs_num,segt_num; 13 char opt[5]; 14 15 void add(int u,int v) 16 { 17 edge[++num_edge].to=v; 18 edge[num_edge].next=head[u]; 19 head[u]=num_edge; 20 } 21 22 void Dfs1(int x) 23 { 24 Sum[x]=1; 25 Depth[x]=Depth[Father[x]]+1; 26 for (int i=head[x]; i; i=edge[i].next) 27 if (edge[i].to!=Father[x]) 28 { 29 Father[edge[i].to]=x; 30 Dfs1(edge[i].to); 31 Sum[x]+=Sum[edge[i].to]; 32 if (!Son[x] || Sum[Son[x]]<Sum[edge[i].to]) 33 Son[x]=edge[i].to; 34 } 35 } 36 37 void Dfs2(int x,int pre) 38 { 39 T_num[x]=++dfs_num; 40 Tree[dfs_num]=a[x]; 41 Top[x]=pre; 42 if (Son[x]) Dfs2(Son[x],pre); 43 for (int i=head[x]; i; i=edge[i].next) 44 if (edge[i].to!=Father[x] && edge[i].to!=Son[x]) 45 Dfs2(edge[i].to,edge[i].to); 46 } 47 48 void Pushup(int now) 49 { 50 Segt[now].val=Segt[Segt[now].ls].val+Segt[Segt[now].rs].val; 51 Segt[now].max=max(Segt[Segt[now].ls].max,Segt[Segt[now].rs].max); 52 } 53 54 void Update(int &now,int l,int r,int x,int k) 55 { 56 if (!now) now=++segt_num; 57 if (l==r) 58 { 59 Segt[now].val=k; 60 Segt[now].max=k; 61 return; 62 } 63 int mid=(l+r)>>1; 64 if (x<=mid) Update(Segt[now].ls,l,mid,x,k); 65 else Update(Segt[now].rs,mid+1,r,x,k); 66 Pushup(now); 67 } 68 69 int Query_Sum(int now,int l,int r,int l1,int r1) 70 { 71 if (now==0) return 0; 72 if (l>r1 || r<l1) return 0; 73 if (l1<=l && r<=r1) 74 return Segt[now].val; 75 int mid=(l+r)>>1; 76 if (r1<=mid) return Query_Sum(Segt[now].ls,l,mid,l1,r1); 77 if (l1>=mid+1) return Query_Sum(Segt[now].rs,mid+1,r,l1,r1); 78 return Query_Sum(Segt[now].ls,l,mid,l1,r1)+Query_Sum(Segt[now].rs,mid+1,r,l1,r1); 79 } 80 81 int Query_Max(int now,int l,int r,int l1,int r1) 82 { 83 if (now==0) return -1; 84 if (l>r1 || r<l1) return -1; 85 if (l1<=l && r<=r1) 86 return Segt[now].max; 87 int mid=(l+r)>>1; 88 if (r1<=mid) return Query_Max(Segt[now].ls,l,mid,l1,r1); 89 if (l1>=mid+1) return Query_Max(Segt[now].rs,mid+1,r,l1,r1); 90 return max(Query_Max(Segt[now].ls,l,mid,l1,r1),Query_Max(Segt[now].rs,mid+1,r,l1,r1)); 91 } 92 93 int Ask_Sum(int x,int y) 94 { 95 int fx=Top[x],fy=Top[y],r=c[x],ans=0; 96 while (fx!=fy) 97 { 98 if (Depth[fx]<Depth[fy]) 99 swap(x,y),swap(fx,fy); 100 ans+=Query_Sum(Root[r],1,n,T_num[fx],T_num[x]); 101 x=Father[fx],fx=Top[x]; 102 } 103 if (Depth[x]<Depth[y]) swap(x,y); 104 ans+=Query_Sum(Root[r],1,n,T_num[y],T_num[x]); 105 return ans; 106 } 107 108 int Ask_Max(int x,int y) 109 { 110 int fx=Top[x],fy=Top[y],r=c[x],ans=0; 111 while (fx!=fy) 112 { 113 if (Depth[fx]<Depth[fy]) 114 swap(x,y),swap(fx,fy); 115 ans=max(ans,Query_Max(Root[r],1,n,T_num[fx],T_num[x])); 116 x=Father[fx],fx=Top[x]; 117 } 118 if (Depth[x]<Depth[y]) swap(x,y); 119 ans=max(ans,Query_Max(Root[r],1,n,T_num[y],T_num[x])); 120 return ans; 121 } 122 123 int main() 124 { 125 scanf("%d%d",&n,&m); 126 for (int i=1; i<=n; ++i) 127 scanf("%d%d",&w[i],&c[i]); 128 for (int i=1; i<=n-1; ++i) 129 { 130 scanf("%d%d",&u,&v); 131 add(u,v); add(v,u); 132 } 133 Dfs1(1); Dfs2(1,1); 134 for (int i=1; i<=n; ++i) 135 Update(Root[c[i]],1,n,T_num[i],w[i]); 136 137 for (int i=1; i<=m; ++i) 138 { 139 scanf("%s%d%d",opt,&x,&y); 140 if (opt[0]=='C' && opt[1]=='C') 141 { 142 Update(Root[c[x]],1,n,T_num[x],0); 143 c[x]=y; 144 Update(Root[c[x]],1,n,T_num[x],w[x]); 145 } 146 if (opt[0]=='C' && opt[1]=='W') 147 { 148 w[x]=y; 149 Update(Root[c[x]],1,n,T_num[x],w[x]); 150 } 151 if (opt[0]=='Q' && opt[1]=='S') 152 printf("%d\n",Ask_Sum(x,y)); 153 if (opt[0]=='Q' && opt[1]=='M') 154 printf("%d\n",Ask_Max(x,y)); 155 } 156 }