# BZOJ_2243

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

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

  1 #include <cstdio>
2 #include <cstring>
3 #include <cstdlib>
4 #include <cmath>
5 #include <algorithm>
6 #include <iostream>
7 using namespace std;
8 const int N = 100003;
9 struct tree1 {
10     tree1* lson;
11     tree1* rson;
12     int sum,l,r,color;
13     bool pd;
14     tree1() {
15         lson = rson = NULL;
16         sum = l = r = color = 0;
17         pd = false;
18     }
19 }* root,dizhi[N*3];
20 int n,m,t;
21 int color[N];
22 int first[N],to[N*2],next_[N*2],eg;
23 inline void addedge(int x,int y) {
24     next_[++eg] = first[x];
25     first[x] = eg;
26     to[eg] = y;
27 }
28 inline void add(int x,int y) {
31 }
32 int fa[N],dep[N],size[N],max_son[N];
33 inline void dfs1(int u) {
34     size[u] = 1;
35     for(int i = first[u] ; i ; i = next_[i]) {
36         int v = to[i];
37         if(v==fa[u]) continue;
38         dep[v] = dep[u] + 1;
39         fa[v] = u;
40         dfs1(v);
41         size[u] += size[v];
42         max_son[u] = size[max_son[u]] > size[v] ? max_son[u] : v;
43     }
44 }
45 int st[N],tt,top[N],hero[N];
46 inline void dfs2(int u,int ctop) {
47     top[u] = ctop;
48     st[u] = ++tt;
49     hero[tt] = u;
50     if(max_son[u]) dfs2(max_son[u],ctop);
51     for(int i = first[u] ; i ; i = next_[i]) {
52         int v = to[i];
53         if(v==fa[u] || v==max_son[u]) continue;
54         dfs2(v,v);
55     }
56 }
57 inline void build(tree1* tree,int l,int r) {
58     if(l==r) {
59         tree->sum = 1;
60         tree->l = tree->r = color[hero[l]];
61         return;
62     }
63     int mid = (l+r)>>1;
64     tree->lson = &dizhi[++t];
65     tree->rson = &dizhi[++t];
66     build(tree->lson,l,mid);
67     build(tree->rson,mid+1,r);
68     tree->sum = tree->lson->sum + tree->rson->sum - (tree->lson->r==tree->rson->l);
69     tree->l = tree->lson->l;
70     tree->r = tree->rson->r;
71 }
72 inline void push_down(tree1* tree) {
73     if(tree->pd) {
74         tree->lson->sum = tree->rson->sum = 1;
75         tree->lson->pd = tree->rson->pd = true;
76         tree->lson->l = tree->lson->r = tree->rson->r = tree->rson->l = tree->color;
77         tree->lson->color = tree->rson->color = tree->color;
78         tree->pd = false;
79     }
80 }
81 inline void modify2(tree1* tree,int l,int r,int x,int y,int c) {
82     if(l!=r) push_down(tree);
83     if(x<=l && r<=y) {
84         tree->sum = 1;
85         tree->l = tree->r = c;
86         tree->pd = true;
87         tree->color = c;
88         return;
89     }
90     int mid = (l+r)>>1;
91     if(!(y<l || mid<x)) modify2(tree->lson,l,mid,x,y,c);
92     if(!(y<mid+1||r<x)) modify2(tree->rson,mid+1,r,x,y,c);
93     tree->sum = tree->lson->sum + tree->rson->sum - (tree->lson->r==tree->rson->l);
94     tree->l = tree->lson->l;
95     tree->r = tree->rson->r;
96 }
97 inline void modify(int x,int y,int c) {
98     while(top[x]!=top[y]) {
99         if(dep[top[x]]  < dep[top[y]]) swap(x,y);
100         modify2(root,1,n,st[top[x]],st[x],c);
101         x = fa[top[x]];
102     }
103     if(dep[x] < dep[y]) swap(x,y);
104     modify2(root,1,n,st[y],st[x],c);
105 }
106 struct merge_ {
107     int sum,l,r;
108     merge_(int sum_= 0,int l_= 0,int r_= 0) {
109         sum = sum_;l = l_;r = r_;
110     }
111 };
112 merge_ query2(tree1* tree,int l,int r,int x,int y) {
113     if(l!=r)push_down(tree);
114     if(x<=l && r<=y)
115         return merge_(tree->sum,tree->l,tree->r);
116     int mid = (l+r)>>1;
117     merge_ q1 = merge_(0,-1,-1);
118     merge_ q2 = merge_(0,-1,-1);
119     if(!(y<l || mid<x)) q1 = query2(tree->lson,l,mid,x,y);
120     if(!(y<mid+1||r<x)) q2 = query2(tree->rson,mid+1,r,x,y);
121     merge_ q3;
122     q3.sum = q1.sum+q2.sum-(q1.r==q2.l);
123     q3.l = q1.l!=-1?q1.l:q2.l;
124     q3.r = q2.r!=-1?q2.r:q1.r;
125     return q3;
126 }
127 inline int query(int x,int y) {
128     merge_ ans1 = merge_(0,-1,-1);
129     merge_ ans2 = merge_(0,-1,-1);
130     while(top[x]!=top[y]) {
131         if(dep[top[x]] < dep[top[y]]) {
132             merge_ linshi = query2(root,1,n,st[top[y]],st[y]);
133             ans2.sum += linshi.sum - (ans2.l==linshi.r);
134             ans2.l = linshi.l;
135             y = fa[top[y]];
136         } else {
137             merge_ linshi = query2(root,1,n,st[top[x]],st[x]);
138             ans1.sum += linshi.sum - (ans1.l==linshi.r);
139             ans1.l = linshi.l;
140             x = fa[top[x]];
141         }
142     }
143     if(dep[x] < dep[y]) {
144         merge_ linshi = query2(root,1,n,st[x],st[y]);
145         return linshi.sum + ans1.sum + ans2.sum - (ans1.l==linshi.l) - (ans2.l==linshi.r);
146     } else {
147         merge_ linshi = query2(root,1,n,st[y],st[x]);
148         return linshi.sum + ans1.sum + ans2.sum - (ans1.l==linshi.r) - (ans2.l==linshi.l);
149     }
150 }
151 int main() {
152     scanf("%d%d",&n,&m);
153     for(int i = 1 ; i <= n ; ++i) scanf("%d",&color[i]);
154     for(int i = 1 ; i < n ; ++i) {
155         int x,y;
156         scanf("%d%d",&x,&y);
158     }
159     dfs1(1);
160     dfs2(1,1);
161     root = &dizhi[++t];
162     build(root,1,n);
163     for(int i = 1 ; i <= m ; ++i) {
164         char haha;
165         int x,y,z;
166         scanf(" %c",&haha);
167         if(haha=='Q') {
168             scanf("%d%d",&x,&y);
169             printf("%d\n",query(x,y));
170         } else {
171             scanf("%d%d%d",&x,&y,&z);
172             modify(x,y,z);
173         }
174     }
175 }
View Code

posted @ 2015-12-28 10:18  443singer  阅读(99)  评论(0编辑  收藏  举报