BZOJ_2243

给定一棵有n个节点的无根树和m个操作,操作有2类:

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

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

请你写一个程序依次完成这m个操作。

 

题解:
链剖裸题+线段树合并,注意合并的时候分清左右区间端点信息

 

  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) {
 29     addedge(x,y);
 30     addedge(y,x);
 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);
157         add(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编辑  收藏  举报