首先我们链剖一下。。。

然后建立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 }
View Code

 

posted on 2014-12-01 21:26  Xs酱~  阅读(298)  评论(0编辑  收藏  举报