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

洛谷 P2486 【[SDOI2011]染色】

时间:2018-01-13 23:43:43      阅读:234      评论:0      收藏:0      [点我收藏+]

标签:ace   shu   const   scan   col   bad   bubuko   ons   else   

题目描述

 技术分享图片

输入输出格式

输入格式:

 

技术分享图片

 

输出格式:

 

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

 

输入输出样例

输入样例#1: 复制
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
输出样例#1: 复制
3
1
2

说明

技术分享图片

题解:

 

树剖,用线段树维护:

 

数组tot[N]表示此时的颜色段数。

 

数组zzz[N]表示此时最左边的节点的颜色。

 

数组yyy[N]表示此时最右边的节点的颜色。

 

则: 首先我们要明确,线段树的叶子节点一定只有一种颜色,也就是一条颜色段。

 

tot[父亲]=tot[左儿子]+tot[右儿子];

 

if (zzz[右儿子]==yyy[左儿子]) {tot[父亲]--;}

 

即如果右儿子的最左边颜色和左儿子的最右边颜色相同,那么肯定有中间部分属于同一颜色段。

 

代码:

  1 #include <cstdio>
  2     #include <cstring>
  3     #include <iostream>
  4     #define k (z+y>>1)
  5     #define ll (r<<1)
  6     #define rr (r<<1|1)
  7     using namespace std;
  8     const int N=1e5+10;int a[N];
  9     int ys[N],s[N*2][2],o[N],cnt,dfn,n;
 10     int zzz[N*4],yyy[N*4],laz[N*4],tot[N*4];
 11     int d[N],siz[N],son[N],top[N],f[N],id[N];
 12     void jia(int a,int b)
 13     {
 14         s[++cnt][1]=o[a];
 15         s[cnt][0]=b;o[a]=cnt;
 16         return;
 17     }
 18     void shang(int r)
 19     {
 20         tot[r]=tot[ll]+tot[rr];
 21         zzz[r]=zzz[ll];yyy[r]=yyy[rr];
 22         if (zzz[rr]==yyy[ll]) tot[r]--;
 23         return;
 24     }
 25     void xiangxia(int r,int z,int y)
 26     {
 27         tot[ll]=tot[rr]=1;
 28         zzz[ll]=zzz[rr]=yyy[ll]=yyy[rr]=laz[ll]=laz[rr]=laz[r];
 29         laz[r]=0;return;
 30     }
 31     void jianshu(int r,int z,int y)
 32     {
 33         if (z==y) {
 34             tot[r]=1;zzz[r]=yyy[r]=ys[a[z]];
 35             return;
 36         }
 37         jianshu(ll,z,k);jianshu(rr,k+1,y);
 38         shang(r);return;
 39     }
 40     void gai(int r,int z,int y,int zz,int yy,int v)
 41     {
 42         if (z==zz&&y==yy) {
 43             tot[r]=1;laz[r]=zzz[r]=yyy[r]=v;
 44             return;
 45         }
 46         if (laz[r]) xiangxia(r,z,y);
 47         if (zz>k) gai(rr,k+1,y,zz,yy,v);
 48         else if (yy<=k) gai(ll,z,k,zz,yy,v);
 49         else {gai(ll,z,k,zz,k,v);gai(rr,k+1,y,k+1,yy,v);}
 50         shang(r);return;
 51     }
 52     int chaxun(int r,int z,int y,int zz,int yy)
 53     {
 54         if (z==zz&&y==yy) return tot[r];
 55         if (laz[r]) xiangxia(r,z,y);
 56         if (zz>k) chaxun(rr,k+1,y,zz,yy);
 57         else if (yy<=k) chaxun(ll,z,k,zz,yy);
 58         else {
 59             int ans=chaxun(ll,z,k,zz,k)+chaxun(rr,k+1,y,k+1,yy);
 60             if (zzz[rr]==yyy[ll]) ans--;
 61             return ans;
 62         }
 63     }
 64     void dfs1(int x,int fa,int dep)
 65     {
 66         f[x]=fa;d[x]=dep;siz[x]=1;
 67         for (int i=o[x];i;i=s[i][1]) {
 68             if (s[i][0]!=fa) {
 69                 dfs1(s[i][0],x,dep+1);
 70                 siz[x]+=siz[s[i][0]];
 71                 if (siz[s[i][0]]>siz[son[x]]) son[x]=s[i][0];
 72             }
 73         }
 74         return;
 75     }
 76     void dfs2(int x,int tp)
 77     {
 78         top[x]=tp;id[x]=++dfn;a[dfn]=x;
 79         if (son[x]) dfs2(son[x],tp);
 80         for (int i=o[x];i;i=s[i][1])
 81         if (s[i][0]!=f[x]&&son[x]!=s[i][0])
 82         dfs2(s[i][0],s[i][0]);
 83         return;
 84     }
 85     void ranse(int x,int y,int v)
 86     {
 87         while (top[x]!=top[y]) {
 88             if (d[top[x]]>d[top[y]]) swap(x,y);
 89             gai(1,1,n,id[top[y]],id[y],v);
 90             y=f[top[y]];
 91         }
 92         if (d[x]>d[y]) swap(x,y);
 93         gai(1,1,n,id[x],id[y],v);
 94         return;
 95     }
 96     int newww(int r,int z,int y,int p)
 97     {
 98         if (z==y) return zzz[r];
 99         if (laz[r]) xiangxia(r,z,y);
100         if (p>k) return newww(rr,k+1,y,p);
101         else return newww(ll,z,k,p);
102     }
103     int xunwen(int x,int y)
104     {
105         int ans=0,nc,fc;
106         while (top[x]!=top[y]) {
107             if (d[top[x]]>d[top[y]]) swap(x,y);
108             ans+=chaxun(1,1,n,id[top[y]],id[y]);
109             nc=newww(1,1,n,id[top[y]]);
110             fc=newww(1,1,n,id[f[top[y]]]);
111             y=f[top[y]];if (nc==fc) ans--;
112         }
113         if (d[x]>d[y]) swap(x,y);
114         ans+=chaxun(1,1,n,id[x],id[y]);
115         return ans?ans:1;
116     }
117     int main()
118     {
119         int m,a,b,c;
120         cin>>n>>m;char caozuo[5];
121         for (int i=1;i<=n;i++) scanf("%d",&ys[i]);
122         for (int i=1;i<n;i++) {
123             scanf("%d%d",&a,&b);jia(a,b);jia(b,a);
124         }
125         dfs1(1,0,1);dfs2(1,1);jianshu(1,1,n);
126         while (m--) {
127             scanf("%s",caozuo);
128             scanf("%d%d",&a,&b);
129             switch (caozuo[0]) {
130                 case C:scanf("%d",&c);
131                 ranse(a,b,c);break;
132          default:
133 
134                 printf("%d\n",xunwen(a,b));break;
135             }
136         }
137         //zhu wo zao dian AC!!!
138         return 0;
139     }

ok!!!

 

洛谷 P2486 【[SDOI2011]染色】

标签:ace   shu   const   scan   col   bad   bubuko   ons   else   

原文地址:https://www.cnblogs.com/fushao2yyj/p/8280738.html

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