首先我们链剖一下。。。
然后建立n棵线段树,分别维护n个不同颜色的信息。
于是MLE 233
其实发现线段树并不会开满的,于是只要动态开点即可。
做完了。
1 /************************************************************** 2 Problem: 3531 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:7692 ms 7 Memory:170268 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <algorithm> 12 13 using namespace std; 14 const int N = 100005; 15 const int M = 10000005; 16 17 struct edge { 18 int next, to; 19 edge() {} 20 edge(int _n, int _t) : next(_n), to(_t) {} 21 } e[N << 1]; 22 23 struct tree_node { 24 int fa, son; 25 int dep, sz, top, w; 26 } tr[N]; 27 int cnt_tree; 28 29 struct segment_node { 30 int mx, sum, lson, rson; 31 } seg[M]; 32 int cnt_seg; 33 34 int n; 35 int first[N], tot; 36 int root[N], c[N], w[N]; 37 38 inline int read() { 39 int x = 0; 40 char ch = getchar(); 41 while (ch < '0' || '9' < ch) 42 ch = getchar(); 43 while ('0' <= ch && ch <= '9') { 44 x = x * 10 + ch - '0'; 45 ch = getchar(); 46 } 47 return x; 48 } 49 50 inline void Add_Edges(int x, int y) { 51 e[++tot] = edge(first[x], y), first[x] = tot; 52 e[++tot] = edge(first[y], x), first[y] = tot; 53 } 54 55 void dfs(int p) { 56 int i, x, y; 57 tr[p].sz = 1; 58 for (x = first[p]; x; x = e[x].next) 59 if (!tr[y = e[x].to].fa) { 60 tr[y].dep = tr[p].dep + 1; 61 tr[y].fa = p; 62 dfs(y); 63 tr[p].sz += tr[y].sz; 64 if (!tr[p].son || tr[tr[p].son].sz < tr[y].sz) 65 tr[p].son = y; 66 } 67 } 68 69 void Dfs(int p) { 70 tr[p].w = ++cnt_tree; 71 if (!tr[p].son) return; 72 tr[tr[p].son].top = tr[p].top; 73 Dfs(tr[p].son); 74 int x, y; 75 for (x = first[p]; x; x = e[x].next) 76 if (tr[y = e[x].to].fa == p && y != tr[p].son) { 77 tr[y].top = y; 78 Dfs(y); 79 } 80 } 81 82 83 #define mid (l + r >> 1) 84 inline void refresh(int p) { 85 seg[p].mx = max(seg[seg[p].lson].mx, seg[seg[p].rson].mx); 86 seg[p].sum = seg[seg[p].lson].sum + seg[seg[p].rson].sum; 87 } 88 89 void update(int &p, int l, int r, int pos, int num) { 90 if (!p) p = ++cnt_seg; 91 if (l == r) { 92 seg[p].mx = seg[p].sum = num; 93 return; 94 } 95 if (pos <= mid) update(seg[p].lson, l, mid, pos, num); 96 else update(seg[p].rson, mid + 1, r, pos, num); 97 refresh(p); 98 } 99 100 int query_mx(int p, int l, int r, int L, int R) { 101 if (!p) return 0; 102 if (L <= l && r <= R) return seg[p].mx; 103 if (R <= mid) return query_mx(seg[p].lson, l, mid, L, R); 104 else if (mid < L) return query_mx(seg[p].rson, mid + 1, r, L, R); 105 else return max(query_mx(seg[p].lson, l, mid, L, R), 106 query_mx(seg[p].rson, mid + 1, r, L, R)); 107 } 108 109 int query_sum(int p, int l, int r, int L, int R) { 110 if (!p) return 0; 111 if (L <= l && r <= R) return seg[p].sum; 112 if (R <= mid) return query_sum(seg[p].lson, l, mid, L, R); 113 else if (mid < L) return query_sum(seg[p].rson, mid + 1, r, L, R); 114 else return query_sum(seg[p].lson, l, mid, L, R) + 115 query_sum(seg[p].rson, mid + 1, r, L, R); 116 } 117 118 119 int work_sum(int x, int y) { 120 int C = c[x], res = 0; 121 while (tr[x].top != tr[y].top) { 122 if (tr[tr[x].top].dep < tr[tr[y].top].dep) 123 swap(x, y); 124 res += query_sum(root[C], 1, n, tr[tr[x].top].w, tr[x].w); 125 x = tr[tr[x].top].fa; 126 } 127 if (tr[x].dep < tr[y].dep) 128 swap(x, y); 129 res += query_sum(root[C], 1, n, tr[y].w, tr[x].w); 130 return res; 131 } 132 133 int work_mx(int x, int y) { 134 int C = c[x], res = 0; 135 while (tr[x].top != tr[y].top) { 136 if (tr[tr[x].top].dep < tr[tr[y].top].dep) 137 swap(x, y); 138 res = max(res, query_mx(root[C], 1, n, tr[tr[x].top].w, tr[x].w)); 139 x = tr[tr[x].top].fa; 140 } 141 if (tr[x].dep < tr[y].dep) 142 swap(x, y); 143 res = max(res, query_mx(root[C], 1, n, tr[y].w, tr[x].w)); 144 return res; 145 } 146 147 148 void build() { 149 int i; 150 for (i = 1; i <= n; ++i) 151 w[i] = read(), c[i] = read(); 152 for (i = 1; i < n; ++i) 153 Add_Edges(read(), read()); 154 tr[1].fa = -1; 155 dfs(1); 156 Dfs(1); 157 for (i = 1; i <= n; ++i) 158 update(root[c[i]], 1, n, tr[i].w, w[i]); 159 } 160 161 void work() { 162 int x, y; 163 char st[10]; 164 scanf("%s", st); 165 x = read(), y = read(); 166 if (st[0] == 'C') 167 if (st[1] == 'C') { 168 update(root[c[x]], 1, n, tr[x].w, 0); 169 update(root[c[x] = y], 1, n, tr[x].w, w[x]); 170 } 171 else update(root[c[x]], 1, n, tr[x].w, w[x] = y); 172 else 173 if (st[1] == 'S') printf("%d\n", work_sum(x, y)); 174 else printf("%d\n", work_mx(x, y)); 175 } 176 177 int main() { 178 int Q; 179 n = read(), Q = read(); 180 build(); 181 while (Q--) 182 work(); 183 return 0; 184 }
By Xs酱~ 转载请说明
博客地址:http://www.cnblogs.com/rausen