树链剖分,线段树维护三个值:区间颜色数、区间左端颜色、区间右端颜色,当左区间右端颜色=右区间左端颜色时候,总颜色-1,树上的维护类似。

  代码

  1 #include<cstdio>
  2 const int M = 1001010;
  3 const int N = 300010;
  4 int dp,p[N],pre[N],tt[N],size[N],f[N],gf[N],go[N],deep[N],color[N];
  5 int id[N],n,m,i,a,b,c,tot,e[N];
  6 int l[M],r[M],lc[M],rc[M],s[M],v[M];
  7 void link(int x,int y)
  8 {
  9     dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y;
 10 }
 11 struct O{
 12     int ans,lc,rc;
 13     void clear()
 14     {
 15         ans=0;lc=0;rc=0;
 16     }
 17     void set(int a,int b,int c)
 18     {
 19         ans=a;lc=b;rc=c;
 20     }
 21 };
 22 void dfs(int x,int fa)
 23 {
 24     int i=p[x];
 25     size[x]=1;
 26     deep[x]=deep[fa]+1;
 27     while (i)
 28     {
 29         if (tt[i]!=fa)
 30         {
 31             f[tt[i]]=x;
 32             dfs(tt[i],x);
 33             if (size[tt[i]]>size[go[x]]) go[x]=tt[i];
 34             size[x]+=size[tt[i]];
 35         }
 36         i=pre[i];
 37     }
 38 }
 39 void gao(int x,int Fa,int fa)
 40 {
 41     int i=p[x];
 42     gf[x]=Fa;id[x]=++tot;e[tot]=color[x];
 43     if (go[x]) gao(go[x],Fa,x);
 44     while (i)
 45     {
 46         if ((tt[i]!=fa)&&(tt[i]!=go[x]))
 47             gao(tt[i],tt[i],x);
 48         i=pre[i];
 49     }
 50 }
 51 void updata(int x)
 52 {
 53     lc[x]=lc[2*x];
 54     rc[x]=rc[2*x+1];
 55     s[x]=s[2*x]+s[2*x+1];
 56     if (rc[2*x]==lc[2*x+1]) s[x]--;
 57 }
 58 void build(int x,int a,int b)
 59 {
 60     int m;
 61     l[x]=a;r[x]=b;v[x]=-1;
 62     if (b-a>1)
 63     {
 64         m=(a+b)>>1;
 65         build(2*x,a,m);
 66         build(2*x+1,m,b);
 67         updata(x);
 68     }
 69     else
 70     {
 71         lc[x]=e[b];
 72         rc[x]=e[b];
 73         s[x]=1;
 74     }
 75 }
 76 void clean(int x)
 77 {
 78     if (v[x]>=0)
 79     {
 80         s[x]=1;
 81         lc[x]=rc[x]=v[x];
 82         v[2*x]=v[x];
 83         v[2*x+1]=v[x];
 84         v[x]=-1;
 85     }
 86 }
 87 void change(int x,int a,int b,int c)
 88 {
 89     int m;
 90     clean(x);
 91     if ((a<=l[x])&&(r[x]<=b))
 92     {
 93         v[x]=c;
 94         return;
 95     }
 96     m=(l[x]+r[x])>>1;
 97     if (a<m) change(2*x,a,b,c);
 98     if (m<b) change(2*x+1,a,b,c);
 99     clean(2*x);clean(2*x+1);
100     updata(x);
101 }
102 O query(int x,int a,int b)
103 {
104     int m;
105     O tmp;tmp.clear();
106     clean(x);
107     if ((a<=l[x])&&(r[x]<=b))
108     {
109         tmp.set(s[x],lc[x],rc[x]);
110         return tmp;
111     }
112     m=(l[x]+r[x])>>1;
113     int L=-1,R=-1,A=-1;
114     if (a<m)
115     {
116         tmp=query(2*x,a,b);
117         L=tmp.lc;
118         R=tmp.rc;
119         A=tmp.ans;
120     }
121     if (m<b)
122     {
123         tmp=query(2*x+1,a,b);
124         if (L==-1)
125         {
126             L=tmp.lc;
127             R=tmp.rc;
128             A=tmp.ans;
129         }
130         else
131         {
132             A+=tmp.ans;
133             if (R==tmp.lc) A--;
134             R=tmp.rc;
135         }
136     }
137     tmp.set(A,L,R);return tmp;
138 }
139 void gai(int a,int b,int c)
140 {
141     while (1)
142     {
143         if (gf[a]==gf[b])
144         {
145             if (deep[a]<deep[b]) a^=b^=a^=b;
146             change(1,id[b]-1,id[a],c);
147             return;
148         }
149         else
150         {
151             if (deep[gf[a]]<deep[gf[b]]) a^=b^=a^=b;
152             change(1,id[gf[a]]-1,id[a],c);
153             a=f[gf[a]];
154         }
155     }
156 }
157 int wen(int a,int b)
158 {
159     int ac=-1,bc=-1,ans=0;
160     while (1)
161     {
162         if (gf[a]==gf[b])
163         {
164             if (deep[a]<deep[b]) a^=b^=a^=b,ac^=bc^=ac^=bc;
165             O tmp=query(1,id[b]-1,id[a]);
166             ans+=tmp.ans;
167             if (tmp.rc==ac) ans--;
168             if (tmp.lc==bc) ans--;
169             return ans;
170         }
171         else
172         {
173             if (deep[gf[a]]<deep[gf[b]]) a^=b^=a^=b,ac^=bc^=ac^=bc;
174             O tmp=query(1,id[gf[a]]-1,id[a]);
175             ans+=tmp.ans;
176             if (tmp.rc==ac) ans--;ac=tmp.lc;
177             a=f[gf[a]];
178         }
179     }
180 }
181 int main()
182 {
183     scanf("%d%d",&n,&m);
184     for (i=1;i<=n;i++)
185         scanf("%d",&color[i]);
186     for (i=1;i<n;i++)
187     {
188         scanf("%d%d",&a,&b);
189         link(a,b);
190         link(b,a);
191     }
192     dfs(1,0);
193     gao(1,1,0);
194     build(1,0,n);
195     for (i=1;i<=m;i++)
196     {
197         char typ;
198         scanf(" %c",&typ);
199         if (typ=='Q')
200         {
201             scanf("%d%d",&a,&b);
202             printf("%d\n",wen(a,b));
203         }
204         else
205         {
206             scanf("%d%d%d",&a,&b,&c);
207             gai(a,b,c);
208         }
209     }
210 }

转载于:https://www.cnblogs.com/fzmh/p/5459459.html

bzoj2243 [SDOI2011]染色相关推荐

  1. [bzoj2243][SDOI2011]染色

    来自FallDream 的博客,未经允许,请勿转载,谢谢qaq 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段 ...

  2. BZOJ2243: [SDOI2011]染色

    Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如 ...

  3. [Bzoj2243][SDOI2011]染色(线段树树剖)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2243 线段树+树链剖分,在线段树需要每次用lt和rt两个数组记录当前区间的左右边界的颜色 ...

  4. BZOJ-2243 [SDOI2011]染色

    树链剖分模版题. #include <cstdlib> #include <cstdio> #include <cstring> #include <algo ...

  5. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  6. P2486 [SDOI2011]染色

    P2486 [SDOI2011]染色 题意: 题解: 与一般的树链剖分相比,不同点在于查询的不是路径上颜色的数量而是颜色段的数量 对于两个颜色段,112和221,两个颜色段数量都是2 如果合在一起颜色 ...

  7. [Luogu 2486] SDOI2011 染色

    [Luogu 2486] SDOI2011 染色 树剖水题,线段树维护. 详细题解不写了. 我只想说我写的线段树又变漂亮了qwq #include <algorithm> #include ...

  8. 洛谷 P2486 [SDOI2011]染色 树链剖分

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 思路 PushDown与Update Q AC代码 总结与拓展 题面 题目链接 P2486 ...

  9. BZOJ 2243: [SDOI2011]染色

    2243: [SDOI2011]染色 >原题链接< Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点 ...

最新文章

  1. 基于点云方式的6D姿态识别
  2. 重写equals和hashCode
  3. Linux网络技术管理
  4. android开发 交换方向,Android实现去哪儿携程地址互换效果
  5. superset中的json数据转csv
  6. HDU - 4497 GCD and LCM
  7. 【youcans 的 OpenCV 例程 200 篇】103. 陷波带阻滤波器消除周期噪声干扰
  8. php edm 系统,edm.php
  9. 软件正在吞噬世界!如何拯救旧金山的开发者?
  10. 转:程序员从初级到中级10个秘诀
  11. 如何判断某版本的.NET Framework是否安装
  12. java magnolia_Web内容管理系统 Magnolia 安装使用-挖掘优良的架构(2)
  13. (一)MATLAB中的输入与输出
  14. WPS Word 快捷键大全
  15. 动态规划法(入门)——最大正方形、最大长方形
  16. 移动硬盘或U盘无法安全弹出怎么快速安全弹出?
  17. 7月18日云栖精选夜读丨蚂蚁金服的“野心”:要做新一代世界级金融科技供应商...
  18. 互联网人群画像和你所不知道的真相
  19. 自定义注解(中英文字段名字映射)
  20. 腾讯优图实验室贾佳亚:加入优图第一年 | 专访

热门文章

  1. Apache POI和EasyExcel 第二集:Apache POI的基本Excel写入(分为03版的xls和07版的xlsx)
  2. java基础入门课后习题_《Java基础入门》课后习题及答案
  3. Java运行作业控制语言_Java安全——语言本身的设计
  4. range.clonecontents 不准确_家长注意!通州今起开展幼升小数据调查,不参加或影响明年入学...
  5. CentOS Linux最常用命令及快捷键整理
  6. h5仿微信聊天(高仿版)、微信聊天表情|对话框|编辑器
  7. live555点播服务器流程深入分析(一)
  8. VMM虚拟机启动失败故障处理
  9. 深入struts2.0(七)--ActionInvocation接口以及3DefaultActionInvocation类
  10. [转]你在修佛,还是在修魔