恩恩树链剖分一下

于是用线段树维护每一个子段的颜色信息 --不同颜色段数,因为要合并所以还要维护每一段的左右端点颜色信息

然后就没有然后了2333

尝试着写了个指针版的。。。感觉还可以啊

话说,是不是写多棵线段树会快啊?

 

  1 /**************************************************************
  2     Problem: 2243
  3     User: rausen
  4     Language: C++
  5     Result: Accepted
  6     Time:4176 ms
  7     Memory:31324 kb
  8 ****************************************************************/
  9  
 10 #include <cstdio>
 11 #include <algorithm>
 12  
 13 using namespace std;
 14 const int N = 100005;
 15 const int M = N << 2;
 16 const int Maxlen = N * 75;
 17  
 18 char buf[Maxlen], *C = buf;
 19 int Len;
 20  
 21 struct edge {
 22     int next, to;
 23     edge() {}
 24     edge(int _n, int _t) : next(_n), to(_t) {}
 25 } e[N << 1];
 26  
 27 int first[N], tot;
 28  
 29 struct tree_node {
 30     int sz, dep, fa, son, top, w;
 31 } tr[N];
 32  
 33 int cnt_tree;
 34  
 35 struct seg_node {
 36     seg_node *lson, *rson;
 37     int l, r, sz, tag, lc, rc;
 38      
 39     inline void fill(int _s, int _t) {
 40         sz = _s;
 41         tag = _t, lc = _t, rc = _t;
 42     }
 43 } *root, mempool[M], *cnt_seg = mempool;
 44  
 45 int n, Q, c[N];
 46  
 47 inline int read() {
 48     int x = 0;
 49     while (*C < '0' || '9' < *C) ++C;
 50     while ('0' <= *C && *C <= '9')
 51         x = x * 10 + *C - '0', ++C;
 52     return x;
 53 }
 54  
 55 inline void Add_Edges(int x, int y) {
 56     e[++tot] = edge(first[x], y), first[x] = tot;
 57     e[++tot] = edge(first[y], x), first[y] = tot;
 58 }
 59  
 60  
 61 void dfs(int p) {
 62     int x, y;
 63     tr[p].sz = 1;
 64     for (x = first[p]; x; x = e[x].next)
 65         if ((y = e[x].to) != tr[p].fa) {
 66             tr[y].dep = tr[p].dep + 1, tr[y].fa = p;
 67             dfs(y);
 68             tr[p].sz += tr[y].sz;
 69             if (!tr[p].son || tr[tr[p].son].sz < tr[y].sz)
 70                 tr[p].son = y;
 71         }
 72 }
 73  
 74 void DFS(int p) {
 75     tr[p].w = ++cnt_tree;
 76     if (!tr[p].son) return;
 77     tr[tr[p].son].top = tr[p].top;
 78     DFS(tr[p].son);
 79     int x, y;
 80     for (x = first[p]; x; x = e[x].next)
 81         if ((y = e[x].to) != tr[p].fa && y != tr[p].son) {
 82             tr[y].top = y;
 83             DFS(y);
 84         }
 85 }
 86  
 87  
 88 #define L p -> l
 89 #define R p -> r
 90 #define Lc p -> lc
 91 #define Rc p -> rc
 92 #define Sz p -> sz
 93 #define Tag p -> tag
 94 #define Lson p -> lson
 95 #define Rson p -> rson
 96 #define mid (l + r >> 1)
 97 void seg_build(seg_node *&p, int l, int r) {
 98     p = ++cnt_seg;
 99     L = l, R = r, Sz = 1, Tag = -1;
100     if (l == r) return;
101     seg_build(Lson, l, mid), seg_build(Rson, mid + 1, r);
102 }
103 #undef mid
104  
105 inline void seg_push_up(seg_node *p) {
106     Lc = Lson -> lc, Rc = Rson -> rc;
107     Sz = Lson -> sz + Rson -> sz;
108     if (Lson -> rc == Rson -> lc) Sz -= 1;
109 }
110  
111 inline void seg_push_down(seg_node *p) {
112     if (Tag == -1 || L == R) {
113         Tag = -1;
114         return;
115     }
116     (*Lson).fill(1, Tag);
117     (*Rson).fill(1, Tag);
118     Tag = -1;
119 }
120  
121 #define mid (L + R >> 1)
122 void seg_update(seg_node *p, int l, int r, int c) {
123     seg_push_down(p);
124     if (l == L && R == r) {
125         (*p).fill(1, c);
126         return;
127     }
128     if (r <= mid) seg_update(Lson, l, r, c);
129     else if (mid < l) seg_update(Rson, l, r, c);
130     else {
131         seg_update(Lson, l, mid, c);
132         seg_update(Rson, mid + 1, r, c);
133     }
134     seg_push_up(p);
135 }
136  
137 int seg_query_cnt(seg_node *p, int l, int r) {
138     seg_push_down(p);
139     if (l == L && R == r) return Sz;
140     if (r <= mid) return seg_query_cnt(Lson, l, r);
141     else if (mid < l) return seg_query_cnt(Rson, l, r);
142     else {
143         return seg_query_cnt(Lson, l, mid) + seg_query_cnt(Rson, mid + 1, r) -
144             (Lson -> rc == Rson -> lc);
145     }
146 }
147  
148 int seg_query_color(seg_node *p, int pos) {
149     seg_push_down(p);
150     if (L == R) return Lc;
151     if (pos <= mid) return seg_query_color(Lson, pos);
152     else return seg_query_color(Rson, pos);
153 }
154 #undef mid
155  
156  
157 void work_change(int x, int y, int c) {
158     while (tr[x].top != tr[y].top) {
159         if (tr[tr[x].top].dep < tr[tr[y].top].dep)
160             swap(x, y);
161         seg_update(root, tr[tr[x].top].w, tr[x].w, c);
162         x = tr[tr[x].top].fa;
163     }
164     if (tr[x].dep < tr[y].dep)
165         swap(x, y);
166     seg_update(root, tr[y].w, tr[x].w, c);
167 }
168  
169 int work_sum(int x, int y) {
170     int res = 0;
171     while (tr[x].top != tr[y].top) {
172         if (tr[tr[x].top].dep < tr[tr[y].top].dep)
173             swap(x, y);
174         res += seg_query_cnt(root, tr[tr[x].top].w, tr[x].w);
175         x = tr[x].top;
176         if (seg_query_color(root, tr[x].w) == seg_query_color(root, tr[tr[x].fa].w))
177             --res;
178         x = tr[x].fa;
179     }
180     if (tr[x].dep < tr[y].dep)
181         swap(x, y);
182     res += seg_query_cnt(root, tr[y].w, tr[x].w);
183     return res;
184 }
185  
186 inline void work() {
187     int x, y, z;
188     while (*C != 'C' && *C != 'Q') ++C;
189     if (*C == 'Q') {
190         x = read(), y = read();
191         printf("%d\n", work_sum(x, y));
192     } else {
193         x = read(), y = read(), z = read();
194         work_change(x, y, z);
195     }
196 }
197  
198 void build() {
199     int i;
200     for (i = 1; i <= n; ++i)
201         c[i] = read();
202     for (i = 1; i < n; ++i)
203         Add_Edges(read(), read());
204     tr[1].fa = -1;
205     dfs(1);
206     DFS(1);
207     seg_build(root, 1, n);
208     for (i = 1; i <= n; ++i)
209         seg_update(root, tr[i].w, tr[i].w, c[i]);
210 }
211  
212 int main() {
213     Len = fread(C , 1, Maxlen, stdin);
214     buf[Len] = '\0';
215     n = read(), Q = read();
216     build();
217     while (Q--) 
218         work();
219     return 0;
220 }
View Code

 

posted on 2014-12-27 22:17  Xs酱~  阅读(213)  评论(0编辑  收藏  举报