码迷,mamicode.com
首页 > 其他好文 > 详细

[BZOJ2243][SDOI2011]染色

时间:2017-09-25 18:52:41      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:php   esc   ref   zoj   splay   getc   problem   data   --   

2243: [SDOI2011]染色

Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 8463  Solved: 3168 [Submit][Status][Discuss]

Description

 

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

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

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

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

 

Input

第一行包含2个整数nm,分别表示节点数和操作数;

第二行包含n个正整数表示n个节点的初始颜色

下面行每行包含两个整数xy,表示xy之间有一条无向边。

下面行每行描述一个操作:

“C a b c”表示这是一个染色操作,把节点a到节点b路径上所有点(包括ab)都染成颜色c

“Q a b”表示这是一个询问操作,询问节点a到节点b(包括ab)路径上的颜色段数量。

 

Output

对于每个询问操作,输出一行答案。

 

Sample Input

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

Sample Output

3

1

2

HINT

数N<=10^5,操作数M<=10^5,所有的颜色C为整数且在[0, 10^9]之间。

 

树剖裸题

技术分享
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<cmath>
  6 #include<algorithm>
  7 using namespace std;
  8 int n,m;
  9 int c[400005];
 10 struct data
 11 {
 12     int next,to;
 13 }e[400005];
 14 int head[400005],cnt;
 15 void add(int u,int v){e[cnt].next=head[u];e[cnt].to=v;head[u]=cnt;cnt++;}
 16 int son[400005],size[400005],fa[400005],dep[400005];
 17 void findson(int now)
 18 {
 19     size[now]=1;
 20     for(int i=head[now];i>=0;i=e[i].next)
 21     {
 22         int to=e[i].to;
 23         if(to==fa[now]) continue;
 24         fa[to]=now;
 25         dep[to]=dep[now]+1;
 26         findson(to);
 27         size[now]+=size[to];
 28         if(size[to]>size[son[now]]) son[now]=to;
 29     }
 30 }
 31 int up[400005],id[400005],p[400005],s;
 32 void dfs(int now,int top)
 33 {
 34     id[now]=++s;
 35     p[s]=now;
 36     up[now]=top;
 37     if(son[now]) dfs(son[now],top);
 38     for(int i=head[now];i>=0;i=e[i].next)
 39     {
 40         int to=e[i].to;
 41         if(to==fa[now]||to==son[now]) continue;
 42         dfs(to,to);
 43     }
 44 }
 45 struct te
 46 {
 47     int lc,rc,color,l,r,lazy;
 48 }t[800005];
 49 void pushup(int now)
 50 {
 51     int l=now<<1,r=l|1;
 52     t[now].lc=t[l].lc;t[now].rc=t[r].rc;
 53     t[now].color=t[l].color+t[r].color;
 54     if(t[l].rc==t[r].lc) t[now].color--;
 55 }
 56 void pushdown(int now)
 57 {
 58     if(!t[now].lazy) return;
 59     int l=now<<1,r=l|1;
 60     t[l].lazy=t[l].lc=t[l].rc=t[r].lazy=t[r].lc=t[r].rc=t[now].lazy;
 61     t[l].color=t[r].color=1;
 62     t[now].lazy=0;
 63 }
 64 void build(int now,int l,int r)
 65 {
 66     t[now].l=l;t[now].r=r;
 67     if(l==r){t[now].color=1;t[now].lc=t[now].rc=c[p[l]];return;}
 68     else
 69     {
 70         int mid=(l+r)>>1;
 71         build(now<<1,l,mid);
 72         build(now<<1|1,mid+1,r);
 73     }
 74     pushup(now);
 75 }
 76 void update(int now,int L,int R,int c)
 77 {
 78     int l=t[now].l,r=t[now].r;
 79     pushdown(now);
 80     if(L<=l&&R>=r){t[now].lc=t[now].rc=t[now].lazy=c;t[now].color=1;return;}
 81     else
 82     {
 83         int mid=(l+r)>>1;
 84         if(L<=mid) update(now<<1,L,R,c);
 85         if(R>mid) update(now<<1|1,L,R,c);
 86     }
 87     pushup(now);
 88 }
 89 int findlca(int a,int b)
 90 {
 91     int x,y;
 92     x=up[a],y=up[b];
 93     while(x!=y)
 94     {
 95         if(dep[x]<dep[y]) swap(x,y),swap(a,b);
 96         a=fa[x];x=up[a];
 97     }
 98     if(dep[a]<dep[b]) swap(a,b);
 99     return b;
100 }
101 int query(int now,int L,int R)
102 {
103     int ans=0;
104     int l=t[now].l,r=t[now].r;
105     pushdown(now);
106     if(L<=l&&R>=r) return t[now].color;
107     else
108     {
109            int mid=(l+r)>>1;
110            if(R<=mid) ans+=query(now<<1,L,R);
111            else if(L>mid) ans+=query(now<<1|1,L,R);
112            else
113            {
114             ans+=query(now<<1,L,R)+query(now<<1|1,L,R);
115             if(t[now<<1].rc==t[now<<1|1].lc) ans--;
116         }
117        }
118        return ans;
119 }
120 void change(int now,int lca,int c)
121 {
122     while(up[now]!=up[lca])
123     {
124            update(1,id[up[now]],id[now],c);
125            now=fa[up[now]];
126        }
127        update(1,id[lca],id[now],c);
128 }
129 int getc(int now,int x)
130 {
131     pushdown(now);
132     int l=t[now].l,r=t[now].r;
133     if(l==r) return t[now].lc;
134     int mid=(l+r)>>1;
135     if(x<=mid)return getc(now<<1,x);
136     else return getc(now<<1|1,x);
137 }
138 
139 int ask(int now,int lca)
140 {
141     int ans=0;
142     while(up[now]!=up[lca])
143     {
144            ans+=query(1,id[up[now]],id[now]);
145            if(getc(1,id[up[now]])==getc(1,id[fa[up[now]]])) ans--;
146            now=fa[up[now]];
147        }
148        return ans+query(1,id[lca],id[now]);
149 }
150 int main()
151 {
152     memset(head,-1,sizeof(head));
153     scanf("%d%d",&n,&m);
154     for(int i=1;i<=n;i++) scanf("%d",&c[i]);
155     for(int i=1;i<=n-1;i++)
156     {
157         int u,v;
158         scanf("%d%d",&u,&v);
159         add(u,v);add(v,u);
160     }
161     dep[1]=1;
162     findson(1);dfs(1,1);build(1,1,n);
163     for(int i=1;i<=m;i++)
164     {
165         char ch[10];
166         scanf("%s",ch);
167         if(ch[0]==C)
168         {
169             int a,b,c;
170             scanf("%d%d%d",&a,&b,&c);
171             int lca=findlca(a,b);
172             change(a,lca,c);change(b,lca,c);
173         }
174         else
175         {
176                int a,b;
177                scanf("%d%d",&a,&b);
178                int lca=findlca(a,b);
179                printf("%d\n",ask(a,lca)+ask(b,lca)-1);
180            }
181     }
182 }
View Code

 

[BZOJ2243][SDOI2011]染色

标签:php   esc   ref   zoj   splay   getc   problem   data   --   

原文地址:http://www.cnblogs.com/wls001/p/7571409.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!