BZOJ_2243 [SDOI2011]染色 【树链剖分+线段树】

一  题目

  [SDOI2011]染色

二 分析

  感觉树链剖分的这些题真的蛮考验码力的,自己的码力还是不够啊!o(╯□╰)o

  还是比较常规的树链剖分,但是一定记得这里的线段树在查询的时候一定要考虑链于链相邻的两个点。

  一开始自己已经把很多坑都已经注意了,包括颜色可以为0,链的相邻点,但怎么就是不正确,还是要多刷题。

三 AC代码

  1 /**************************************************************
  2     Problem: 2243
  3     User: Dybala21
  4     Language: C++
  5     Result: Accepted
  6     Time:6652 ms
  7     Memory:18580 kb
  8 ****************************************************************/
  9  
 10 #include <bits/stdc++.h>
 11 using namespace std;
 12 const int MAXN = 1e5 + 15;
 13 int n, m;
 14 int c[MAXN];
 15 struct Edge
 16 {
 17     int to, next;
 18 }edge[MAXN<<1];
 19 int head[MAXN], tot;
 20 int e[MAXN][2];
 21 int fa[MAXN], deep[MAXN], sz[MAXN], son[MAXN];
 22 int p[MAXN], top[MAXN];
 23 int pos;
 24  
 25 void init()
 26 {
 27     tot = 0, pos = 0;
 28     memset(head, -1, sizeof(head));
 29     memset(son, -1, sizeof(son));
 30 }
 31 void addedge(int u, int v)
 32 {
 33     edge[tot].to = v;
 34     edge[tot].next = head[u];
 35     head[u] = tot++;  
 36 }
 37 void dfs1(int u, int pre, int d)
 38 {
 39     fa[u] = pre;
 40     sz[u] = 1;
 41     deep[u] = d;
 42     for(int i = head[u]; i != -1; i = edge[i].next)
 43     {
 44         int v = edge[i].to;
 45         if(v != pre)
 46         {
 47             dfs1(v, u, d + 1);
 48             sz[u] += sz[v];
 49             if(son[u] == -1 || sz[v] > sz[son[u]])
 50                 son[u] = v;
 51         }
 52     }
 53 }
 54 void dfs2(int u, int sp)
 55 {
 56     p[u] = ++pos;
 57     top[u] = sp;
 58     if(son[u] != -1)
 59         dfs2(son[u], sp);
 60     else
 61         return;
 62     for(int i = head[u]; i != -1; i = edge[i].next)
 63     {
 64         int v = edge[i].to;
 65         if(v != fa[u] && v != son[u])
 66             dfs2(v, v);
 67     }
 68 }
 69 int lca(int x, int y)
 70 {
 71     int f1 = top[x], f2 = top[y];
 72     while(f1 != f2)
 73     {
 74          
 75         if(deep[f1] < deep[f2])
 76         {
 77             swap(f1, f2);
 78             swap(x, y);
 79         }
 80         x = fa[f1];
 81         f1 = top[x];
 82     }
 83     if(deep[x] < deep[y])   swap(x, y);
 84     return y;
 85 }
 86 struct Node
 87 {
 88     int l, r;
 89     int lc, rc;
 90     int lazy, sum;
 91 }segTree[MAXN*3];
 92 void pushdown(int rt)
 93 {
 94     int tmp = segTree[rt].lazy;
 95     segTree[rt].lazy = -1;
 96     if(tmp == -1 || segTree[rt].l == segTree[rt].r)
 97         return;
 98     segTree[rt<<1].lc = segTree[rt<<1].rc = tmp;
 99     segTree[rt<<1|1].lc = segTree[rt<<1|1].rc = tmp;
100     segTree[rt<<1].sum = segTree[rt<<1|1].sum = 1;
101     segTree[rt<<1].lazy = segTree[rt<<1|1].lazy = tmp;
102 }
103 void maintain(int rt)
104 {
105     segTree[rt].sum = segTree[rt<<1].sum + segTree[rt<<1|1].sum;
106     if(segTree[rt<<1].rc == segTree[rt<<1|1].lc)
107         segTree[rt].sum--;
108     segTree[rt].lc = segTree[rt<<1].lc;
109     segTree[rt].rc = segTree[rt<<1|1].rc;
110 }
111 void build(int rt, int l, int r)
112 {
113     segTree[rt].l = l;
114     segTree[rt].r = r;
115     segTree[rt].lazy = -1;    
116     segTree[rt].sum = 0;
117     if(l == r)
118         return;
119     int mid = (l + r) >> 1;
120     build(rt<<1, l, mid);
121     build(rt<<1|1, mid + 1, r);
122 }
123 void update(int rt, int l, int r, int val)
124 {
125     pushdown(rt);
126     if(segTree[rt].l == l && segTree[rt].r == r)
127     {
128         segTree[rt].lazy = val;
129         segTree[rt].lc = segTree[rt].rc = val;
130         segTree[rt].sum = 1;
131         return;
132     }
133     int mid = (segTree[rt].l + segTree[rt].r) >> 1;
134     if(r <= mid)
135         update(rt<<1, l, r, val);
136     else if(l > mid)
137         update(rt<<1|1, l, r, val);
138     else
139     {
140         update(rt<<1, l, mid, val);
141         update(rt<<1|1, mid+1, r, val);
142     }
143     maintain(rt);
144 }
145 void update(int x, int y, int val)
146 {
147     while(top[x] != top[y])
148     {
149         if(deep[top[x]] < deep[top[y]])
150             swap(x, y);
151         update(1, p[top[x]], p[x], val);
152         x = fa[top[x]];
153     }
154     if(deep[x] < deep[y])
155         swap(x, y);
156     update(1, p[y], p[x], val);
157 }
158 int query(int rt, int l, int r)
159 {
160     pushdown(rt);
161     if(segTree[rt].l == l && segTree[rt].r == r)
162         return segTree[rt].sum;
163     int mid = (segTree[rt].l + segTree[rt].r) >> 1;
164     int ans = 0;
165     if(r <= mid)
166         ans += query(rt<<1, l, r);
167     else if(l > mid)
168         ans += query(rt<<1|1, l, r);
169     else
170     {
171         ans += query(rt<<1, l, mid);
172         ans += query(rt<<1|1, mid + 1, r);
173         if(segTree[rt<<1].rc == segTree[rt<<1|1].lc)
174             ans--;
175     }
176     return ans;
177 }
178 int find(int rt, int x)
179 {
180     pushdown(rt);
181     if(segTree[rt].l == segTree[rt].r)
182         return segTree[rt].lc;
183     int mid = (segTree[rt].l + segTree[rt].r) >> 1;
184     if(x <= mid)
185         return find(rt<<1, x);
186     else
187         return find(rt<<1|1, x);
188 }
189 int query(int x, int y)
190 {
191     int res = 0;
192     while(top[x] != top[y])
193     {
194         if(deep[top[x]] < deep[top[y]])
195             swap(x, y);
196         res += query(1, p[top[x]], p[x]);
197         if(find(1, p[top[x]]) == find(1, p[fa[top[x]]]))
198             res--;
199         x = fa[top[x]];
200     }
201     if(deep[x] < deep[y])
202         swap(x, y);
203     res += query(1, p[y], p[x]);
204     return res;
205 }
206 int main()
207 {
208     //freopen("in.txt", "r", stdin);
209     init();
210     scanf("%d%d", &n, &m);
211     for(int i = 1; i <= n; i++)
212         scanf("%d", &c[i]);
213     for(int i = 0; i < n - 1; i++)
214     {
215         scanf("%d%d", &e[i][0], &e[i][1]);
216         addedge(e[i][0], e[i][1]);
217         addedge(e[i][1], e[i][0]);
218     }
219     dfs1(1, 1, 1);
220     dfs2(1, 1);
221     build(1, 1, pos);
222     for(int i = 1; i <= n; i++)
223         update(1, p[i], p[i], c[i]);
224     char op;
225     int a, b, val;
226     for(int i = 0; i < m; i++)
227     {
228         scanf(" %c %d %d", &op, &a, &b);
229         if(op == 'Q')
230         {
231             printf("%d\n", query(a, b));
232         }
233         else
234         {
235             scanf("%d", &val);
236             update(a, b, val);
237         }
238     }
239     return 0;
240 }
241 

 

posted @ 2019-05-11 23:57  Dybala21  阅读(146)  评论(0编辑  收藏  举报