# BZOJ 2243: [SDOI2011]染色

## 2243: [SDOI2011]染色

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 3732  Solved: 1420

## Description

1、将节点a到节点b路径上所有点都染成颜色c；

2、询问节点a到节点b路径上的颜色段数量（连续相同颜色被认为是同一段），如“112221”3段组成：“11”、“222”和“1”

## Input

“C a b c”表示这是一个染色操作，把节点a到节点b路径上所有点（包括a和b）都染成颜色c；

“Q a b”表示这是一个询问操作，询问节点a到节点b（包括a和b）路径上的颜色段数量。

6 5
2 2 1 2 1 1
1 2
1 3
2 4
2 5
2 6
Q 3 5
C 2 1 1
Q 3 5
C 5 1 2
Q 3 5

3

1

2

## HINT

Source

  1 #include <bits/stdc++.h>
2 using namespace std;
3 const int maxn = 100010;
4 struct arc {
5     int to,next;
6     arc(int x = 0,int y = -1) {
7         to = x;
8         next = y;
9     }
10 } e[maxn<<1];
11 struct node {
12     int lt,rt,lcolor,rcolor,sum,lazy;
13 } tree[maxn<<2];
15 int son[maxn],siz[maxn],loc[maxn];
16 int clk,tot;
17 void add(int u,int v) {
20 }
21 void FindHeavyEdge(int u,int father,int depth) {
22     fa[u] = father;
23     dep[u] = depth;
24     son[u] = -1;
25     siz[u] = 1;
26     for(int i = head[u]; ~i; i = e[i].next) {
27         if(e[i].to == father) continue;
28         FindHeavyEdge(e[i].to,u,depth + 1);
29         siz[u] += siz[e[i].to];
30         if(son[u] == -1 || siz[e[i].to] > siz[son[u]])
31             son[u] = e[i].to;
32     }
33 }
34 void ConnectHeavyEdge(int u,int ancestor) {
35     top[u] = ancestor;
36     loc[u] = clk++;
37     if(son[u] != -1) ConnectHeavyEdge(son[u],ancestor);
38     for(int i = head[u]; ~i; i = e[i].next) {
39         if(e[i].to == fa[u] || e[i].to == son[u]) continue;
40         ConnectHeavyEdge(e[i].to,e[i].to);
41     }
42 }
43 inline void pushdown(int v) {
44     if(tree[v].lazy != -1) {
45         tree[v<<1].lazy = tree[v].lazy;
46         tree[v<<1|1].lazy = tree[v].lazy;
47         tree[v<<1].lcolor = tree[v<<1].rcolor = tree[v].lazy;
48         tree[v<<1|1].lcolor = tree[v<<1|1].rcolor = tree[v].lazy;
49         tree[v].lazy = -1;
50         tree[v<<1].sum = tree[v<<1|1].sum = 1;
51     }
52 }
53 inline void pushup(int v){
54     tree[v].sum = tree[v<<1].sum + tree[v<<1|1].sum;
55     if(tree[v<<1].rcolor == tree[v<<1|1].lcolor) tree[v].sum--;
56     tree[v].lcolor = tree[v<<1].lcolor;
57     tree[v].rcolor = tree[v<<1|1].rcolor;
58 }
59 void build(int lt,int rt,int v) {
60     tree[v].lt = lt;
61     tree[v].rt = rt;
62     tree[v].lazy = -1;
63     if(lt == rt) {
64         tree[v].lcolor = tree[v].rcolor = -1;
65         tree[v].sum = 1;
66         return;
67     }
68     int mid = (lt + rt)>>1;
69     build(lt,mid,v<<1);
70     build(mid + 1,rt,v<<1|1);
71     pushup(v);
72 }
73 void update(int lt,int rt,int color,int v) {
74     if(lt <= tree[v].lt && rt >= tree[v].rt) {
75         tree[v].lcolor = tree[v].rcolor = color;
76         tree[v].lazy = color;
77         tree[v].sum = 1;
78         return;
79     }
80     pushdown(v);
81     if(lt <= tree[v<<1].rt) update(lt,rt,color,v<<1);
82     if(rt >= tree[v<<1|1].lt) update(lt,rt,color,v<<1|1);
83     pushup(v);
84 }
85 int query(int lt,int rt,int v) {
86     if(lt == tree[v].lt && rt == tree[v].rt) return tree[v].sum;
87     pushdown(v);
88     if(rt <= tree[v<<1].rt) return query(lt,rt,v<<1);
89     if(lt >= tree[v<<1|1].lt) return query(lt,rt,v<<1|1);
90     int tmp = query(lt,tree[v<<1].rt,v<<1) + query(tree[v<<1|1].lt,rt,v<<1|1);
91     if(tree[v<<1].rcolor == tree[v<<1|1].lcolor) tmp--;
92     pushup(v);
93     return tmp;
94 }
95 void CHANGE(int u,int v,int color) {
96     while(top[u] != top[v]) {
97         if(dep[top[u]] < dep[top[v]]) swap(u,v);
98         update(loc[top[u]],loc[u],color,1);
99         u = fa[top[u]];
100     }
101     if(dep[u] > dep[v]) swap(u,v);
102     update(loc[u],loc[v],color,1);
103 }
104 int getColor(int pos,int v){
105     if(tree[v].lt == tree[v].rt) return tree[v].lcolor;
106     pushdown(v);
107     if(pos <= tree[v<<1].rt) return getColor(pos,v<<1);
108     if(pos >= tree[v<<1|1].lt) return getColor(pos,v<<1|1);
109     pushup(v);
110 }
111 int QUERY(int u,int v) {
112     int ret = 0;
113     while(top[u] != top[v]) {
114         if(dep[top[u]] < dep[top[v]]) swap(u,v);
115         ret += query(loc[top[u]],loc[u],1);
116         if(getColor(loc[top[u]],1) == getColor(loc[fa[top[u]]],1)) --ret;
117         u = fa[top[u]];
118     }
119     if(dep[u] > dep[v]) swap(u,v);
120     ret += query(loc[u],loc[v],1);
121     return ret;
122 }
123 int val[maxn],n,m;
124 int main() {
125     int u,v,color;
126     while(~scanf("%d%d",&n,&m)) {
128         tot = clk = 0;
129         for(int i = 1; i <= n; ++i) scanf("%d",val + i);
130         for(int i = 1; i < n; ++i) {
131             scanf("%d%d",&u,&v);
134         }
135         FindHeavyEdge(1,0,0);
136         ConnectHeavyEdge(1,1);
137         build(0,clk-1,1);
138         for(int i = 1; i <= n; ++i)
139             update(loc[i],loc[i],val[i],1);
140         char op[10];
141         while(m--) {
142             scanf("%s",op);
143             if(op[0] == 'Q') {
144                 scanf("%d%d",&u,&v);
145                 printf("%d\n",QUERY(u,v));
146             } else if(op[0] == 'C') {
147                 scanf("%d%d%d",&u,&v,&color);
148                 CHANGE(u,v,color);
149             }
150         }
151     }
152     return 0;
153 }
154 /*
155 6 5
156 2 2 1 2 1 1
157 1 2
158 1 3
159 2 4
160 2 5
161 2 6
162 Q 3 5
163 C 2 1 1
164 Q 3 5
165 C 5 1 2
166 Q 3 5
167 */
View Code

posted @ 2015-09-29 08:34  狂徒归来  阅读(244)  评论(0编辑  收藏  举报