# bzoj 2243（大学ACM恢复训练）

## 2243: [SDOI2011]染色

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 10083  Solved: 3843
[Submit][Status][Discuss]

## Description

1、将节点a到节点b路径上所有点都染成颜色c；
2、询问节点a到节点b路径上的颜色段数量（连续相同颜色被认为是同一段），

  1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 using namespace std;
6 #define maxn 100020
7
8 struct node{
9     int next,to;
10 }e[maxn * 2];
11 struct data{
12     int lc,rc,num;
13     data(){ lc = rc = num = 0; }
14     data(int a,int b,int c):lc(a),rc(b),num(c){};
15 };
16 struct node2{
17     int ls,rs,tag;
18     data dt;
19 }sgt[maxn * 20];
21 int n,m,col[maxn],tot,root[maxn];
22 int sz[maxn],son[maxn],fa[maxn],id[maxn],top[maxn],dth[maxn],len[maxn];
23
24 inline void adde(int x,int y){
25     e[++cnt].to = y;
28 }
29 void dfs(int x){
30     sz[x] = 1;
31     for (int i = head[x] ; i ; i = e[i].next){
32         if ( e[i].to == fa[x] ) continue;
33         fa[e[i].to] = x , dth[e[i].to] = dth[x] + 1;
34         dfs(e[i].to);
35         sz[x] += sz[e[i].to];
36         if ( sz[son[x]] < sz[e[i].to] ) son[x] = e[i].to;
37     }
38 }
39 void dfs2(int x){
40     if ( son[x] ){
41         top[son[x]] = top[x] , id[son[x]] = ++len[top[x]];
42         dfs2(son[x]);
43     }
44     for (int i = head[x] ; i ; i = e[i].next){
45         if ( e[i].to == fa[x] || e[i].to == son[x] ) continue;
46         top[e[i].to] = e[i].to , id[e[i].to] = len[e[i].to] = 1;
47         dfs2(e[i].to);
48     }
49 }
50 inline data update(data dt1,data dt2){
51     data cur;
52     cur.num = dt1.num + dt2.num - (dt1.rc == dt2.lc);
53     if ( dt1.num && dt2.num ) cur.lc = dt1.lc , cur.rc = dt2.rc;
54     else if ( dt1.num ) cur.lc = dt1.lc , cur.rc = dt1.rc;
55     else if ( dt2.num ) cur.lc = dt2.lc , cur.rc = dt2.rc;
56     return cur;
57 }
58 inline void cov(int x,int c){
59     if ( !x ) return;
60     sgt[x].dt = data(c,c,1);
61     sgt[x].tag = c;
62 }
63 inline void pushdown(int x){
64     if ( sgt[x].tag != -1 ){
65         int ls = sgt[x].ls , rs = sgt[x].rs;
66         cov(ls,sgt[x].tag) , cov(rs,sgt[x].tag);
67         sgt[x].tag = -1;
68     }
69 }
70 /*inline void update(int x){
71     int ls = sgt[x].ls , rs = sgt[x].rs;
72     sgt[x].num = sgt[ls].num + sgt[rs].num - (sgt[ls].rc == sgt[rs].lc);
73     if ( ls && rs ) sgt[x].lc = sgt[ls].lc , sgt[x].rc = sgt[rs].rc;
74     else if ( ls ) sgt[x].lc = sgt[ls].lc , sgt[x].rc = sgt[ls].rc;
75     else sgt[x].lc = sgt[rs].lc , sgt[x].rc = sgt[rs].rc;
76 }*/
77 void insert(int &x,int l,int r,int id,int c){
78     if ( !x ) x = ++tot , sgt[x].tag = -1;
79     if ( l == r ){    sgt[x].dt = data(c,c,1); return; }
80     int mid = (l + r) >> 1;
81     if ( id <= mid ) insert(sgt[x].ls,l,mid,id,c);
82     else insert(sgt[x].rs,mid + 1,r,id,c);
83     sgt[x].dt = update(sgt[sgt[x].ls].dt,sgt[sgt[x].rs].dt);
84 }
85 void build(){
86     for (int i = 1 ; i <= n ; i++)
87         insert(root[top[i]],1,len[top[i]],id[i],col[i]);
88 }
89 void modify(int x,int l,int r,int ls,int rs,int c){
90     if ( !x ) return;
91     if ( ls <= l && rs >= r ){ cov(x,c); return; }
92     pushdown(x);
93     int mid = (l + r) >> 1;
94     if ( ls <= mid ) modify(sgt[x].ls,l,mid,ls,rs,c);
95     if ( rs > mid ) modify(sgt[x].rs,mid + 1,r,ls,rs,c);
96     sgt[x].dt = update(sgt[sgt[x].ls].dt,sgt[sgt[x].rs].dt);
97 }
98 data query(int x,int l,int r,int ls,int rs){
99     if ( !x ) return data(0,0,0);
100     pushdown(x);
101     if ( ls <= l && rs >= r ) return sgt[x].dt;
102     int mid = (l + r) >> 1; data dt1,dt2;
103     if ( ls <= mid ) dt1 = query(sgt[x].ls,l,mid,ls,rs);
104     if ( rs > mid ) dt2 = query(sgt[x].rs,mid + 1,r,ls,rs);
105     return update(dt1,dt2);
106 }
107 int query(int x,int y){
108     data dt1,dt2,dt3;
109     while ( top[x] != top[y] ){
110         if ( dth[top[x]] > dth[top[y]] ){
111             dt1 = update(query(root[top[x]],1,len[top[x]],1,id[x]),dt1); //左边深度更小，注意合并顺序
112             x = fa[top[x]];
113         }
114         else{
115             dt2 = update(query(root[top[y]],1,len[top[y]],1,id[y]),dt2);
116             y = fa[top[y]];
117         }
118     }
119     //链顶合并有特殊情况
120     if ( dth[x] < dth[y] )
121         dt2 = update(query(root[top[x]],1,len[top[x]],id[x],id[y]),dt2);
122     else
123         dt1 = update(query(root[top[x]],1,len[top[x]],id[y],id[x]),dt1);
124     swap(dt1.lc,dt1.rc);
125     return update(dt1,dt2).num;
126 }
127 void modify(int x,int y,int c){
128     while ( top[x] != top[y] ){
129         if ( dth[top[x]] < dth[top[y]] ) swap(x,y);
130         modify(root[top[x]],1,len[top[x]],1,id[x],c);
131         x = fa[top[x]];
132     }
133     if ( dth[x] < dth[y] ) modify(root[top[x]],1,len[top[x]],id[x],id[y],c);
134     else modify(root[top[x]],1,len[top[x]],id[y],id[x],c);
135 }
136 int main(){
137     freopen("input.txt","r",stdin);
138     scanf("%d %d",&n,&m);
139     for (int i = 1 ; i <= n ; i++) scanf("%d",&col[i]);
140     for (int i = 1 ; i < n ; i++){
141         int x,y;
142         scanf("%d %d",&x,&y);
144     }
145     dfs(1) , id[1] = len[1] = top[1] = 1 , dfs2(1) , build();
146     while ( m-- ){
147         char ch[10]; int a,b,c;
148         scanf("%s",ch);
149         if ( ch[0] == 'Q' ){
150             scanf("%d %d",&a,&b);
151             printf("%d\n",query(a,b));
152         }
153         else{
154             scanf("%d %d %d",&a,&b,&c);
155             modify(a,b,c);
156         }
157     }
158     return 0;
159 }
View Code

posted @ 2018-06-29 12:01  zhangqingqi  阅读(120)  评论(0编辑  收藏  举报