题目描述

输入输出格式

输入格式:

输出格式:

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

输入输出样例

输入样例#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[父亲]--;}

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

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#define k (z+y>>1)
#define ll (r<<1)
#define rr (r<<1|1)
using namespace std;
const int N=1e5+;int a[N];
int ys[N],s[N*][],o[N],cnt,dfn,n;
int zzz[N*],yyy[N*],laz[N*],tot[N*];
int d[N],siz[N],son[N],top[N],f[N],id[N];
void jia(int a,int b)
{
s[++cnt][]=o[a];
s[cnt][]=b;o[a]=cnt;
return;
}
void shang(int r)
{
tot[r]=tot[ll]+tot[rr];
zzz[r]=zzz[ll];yyy[r]=yyy[rr];
if (zzz[rr]==yyy[ll]) tot[r]--;
return;
}
void xiangxia(int r,int z,int y)
{
tot[ll]=tot[rr]=;
zzz[ll]=zzz[rr]=yyy[ll]=yyy[rr]=laz[ll]=laz[rr]=laz[r];
laz[r]=;return;
}
void jianshu(int r,int z,int y)
{
if (z==y) {
tot[r]=;zzz[r]=yyy[r]=ys[a[z]];
return;
}
jianshu(ll,z,k);jianshu(rr,k+,y);
shang(r);return;
}
void gai(int r,int z,int y,int zz,int yy,int v)
{
if (z==zz&&y==yy) {
tot[r]=;laz[r]=zzz[r]=yyy[r]=v;
return;
}
if (laz[r]) xiangxia(r,z,y);
if (zz>k) gai(rr,k+,y,zz,yy,v);
else if (yy<=k) gai(ll,z,k,zz,yy,v);
else {gai(ll,z,k,zz,k,v);gai(rr,k+,y,k+,yy,v);}
shang(r);return;
}
int chaxun(int r,int z,int y,int zz,int yy)
{
if (z==zz&&y==yy) return tot[r];
if (laz[r]) xiangxia(r,z,y);
if (zz>k) chaxun(rr,k+,y,zz,yy);
else if (yy<=k) chaxun(ll,z,k,zz,yy);
else {
int ans=chaxun(ll,z,k,zz,k)+chaxun(rr,k+,y,k+,yy);
if (zzz[rr]==yyy[ll]) ans--;
return ans;
}
}
void dfs1(int x,int fa,int dep)
{
f[x]=fa;d[x]=dep;siz[x]=;
for (int i=o[x];i;i=s[i][]) {
if (s[i][]!=fa) {
dfs1(s[i][],x,dep+);
siz[x]+=siz[s[i][]];
if (siz[s[i][]]>siz[son[x]]) son[x]=s[i][];
}
}
return;
}
void dfs2(int x,int tp)
{
top[x]=tp;id[x]=++dfn;a[dfn]=x;
if (son[x]) dfs2(son[x],tp);
for (int i=o[x];i;i=s[i][])
if (s[i][]!=f[x]&&son[x]!=s[i][])
dfs2(s[i][],s[i][]);
return;
}
void ranse(int x,int y,int v)
{
while (top[x]!=top[y]) {
if (d[top[x]]>d[top[y]]) swap(x,y);
gai(,,n,id[top[y]],id[y],v);
y=f[top[y]];
}
if (d[x]>d[y]) swap(x,y);
gai(,,n,id[x],id[y],v);
return;
}
int newww(int r,int z,int y,int p)
{
if (z==y) return zzz[r];
if (laz[r]) xiangxia(r,z,y);
if (p>k) return newww(rr,k+,y,p);
else return newww(ll,z,k,p);
}
int xunwen(int x,int y)
{
int ans=,nc,fc;
while (top[x]!=top[y]) {
if (d[top[x]]>d[top[y]]) swap(x,y);
ans+=chaxun(,,n,id[top[y]],id[y]);
nc=newww(,,n,id[top[y]]);
fc=newww(,,n,id[f[top[y]]]);
y=f[top[y]];if (nc==fc) ans--;
}
if (d[x]>d[y]) swap(x,y);
ans+=chaxun(,,n,id[x],id[y]);
return ans?ans:;
}
int main()
{
int m,a,b,c;
cin>>n>>m;char caozuo[];
for (int i=;i<=n;i++) scanf("%d",&ys[i]);
for (int i=;i<n;i++) {
scanf("%d%d",&a,&b);jia(a,b);jia(b,a);
}
dfs1(,,);dfs2(,);jianshu(,,n);
while (m--) {
scanf("%s",caozuo);
scanf("%d%d",&a,&b);
switch (caozuo[]) {
case 'C':scanf("%d",&c);
ranse(a,b,c);break;
         default: printf("%d\n",xunwen(a,b));break;
}
}
//zhu wo zao dian AC!!!
return ;
}

ok!!!

洛谷 P2486 [SDOI2011]染色的更多相关文章

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

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

  2. 洛谷 P2486 [SDOI2011]染色/bzoj 2243: [SDOI2011]染色 解题报告

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

  3. 洛谷 P2486 [SDOI2011]染色 LCT

    Code: #include <cstdio> //SDOI2010 染色 #include <algorithm> #include <cstring> #inc ...

  4. 洛谷P2486 [SDOI2011]染色 题解 树链剖分+线段树

    题目链接:https://www.luogu.org/problem/P2486 首先这是一道树链剖分+线段树的题. 线段树部分和 codedecision P1112 区间连续段 一模一样,所以我们 ...

  5. 洛谷 P2486 [SDOI2011]染色(树链剖分+线段树)

    题目链接 题解 比较裸的树链剖分 好像树链剖分的题都很裸 线段树中维护一个区间最左和最右的颜色,和答案 合并判断一下中间一段就可以了 比较考验代码能力 Code #include<bits/st ...

  6. 洛谷P2486 [SDOI2011]染色

    题目描述 输入输出格式 输入格式: 输出格式: 对于每个询问操作,输出一行答案. 输入输出样例 输入样例#1: 6 5 2 2 1 2 1 1 1 2 1 3 2 4 2 5 2 6 Q 3 5 C ...

  7. 洛谷P2486 [SDOI2011]染色(树链剖分+线段树判断边界)

    [题目链接] [思路]: 涉及到树上区间修改操作,所以使用树链剖分,涉及到区间查询,所以使用线段树. update操作时,就正常操作,难点在于query操作的计数. 因为树链剖分的dfs序只能保证一条 ...

  8. 洛谷$P2486\ [SDOI2011]$染色 线段树+树链剖分

    正解:线段树+树链剖分 解题报告: 传送门$QwQ$ 其实是道蛮板子的题,,,但因为我写得很呆然后写了贼久之后发现想法有问题要重构,就很难受,就先写个题解算了$kk$ 考虑先跑个树剖,然后按$dfn$ ...

  9. BZOJ2243 洛谷2486 [SDOI2011]染色 树链剖分

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2243 题目传送门 - 洛谷2486 题意概括 一棵树,共n个节点. 让你支持以下两种操作,共m次操 ...

随机推荐

  1. Spring管理的bean初始化方法的三种方式,以及@PostConstruct不起作用的原因

    1:Spring 容器中的 Bean 是有生命周期的,spring 允许 Bean 在初始化完成后以及销毁前执行特定的操作.下面是常用的三种指定特定操作的方法: 通过实现InitializingBea ...

  2. 用Fiddler或Charles进行mock数据搭建测试环境

    转载:http://blog.csdn.net/qqYJ5/article/details/62216582 应用场景:服务器数据不符合测试条件或者服务器未开发完成时,我们可以通过在本地创建数据来达到 ...

  3. A read-only user or a user in a read-only database is not permitted to disable

    A read-only user or a user in a read-only database is not permitted to disable 出现如题的问题通常是由于db.lck的所属 ...

  4. C5:单例模式 Singleton

    保证一个类仅有一个实例,并提供一个访问它的全局访问点. 应用场景:A.一个无状态的类使用单例,可以节省内存B.全局或配置类(其实这个也是无状态的)C.脚本或程序从运行开始到结束,仅需要一个实例来保证数 ...

  5. flashplayer

    http://www.adobe.com/support/flashplayer/downloads.html

  6. 代理工具Charles使用

    代理工具Charles使用 分类: MAC 2014-03-27 20:41 7810人阅读 评论(2) 收藏 举报 手机开发 一.跟踪HTTPS 1.下载官方的证书ssl.zip证书,解压成*.cr ...

  7. lua连接数据库之luasql ------ luasql连接mysql数据库 及 luasql源码编译

    lua连接数据库不只luasql这个库,但目前更新最快的的貌似是这个luasql,他是开源的,支持的数据库功能如下: Connect to ODBC, ADO, Oracle, MySQL, SQLi ...

  8. 【优才原创】Android的拖放机制

    优才网 [优才原创]Android的拖放机制 2016-04-18 优才学院 优才网 一.拖放机制概述 ² 拖放操作是手指触摸屏幕上的某一对象.然后拖动该对象.最后在屏幕的某个位置释放该对象并运行某种 ...

  9. ros之串口通信---imu

    1.sudo apt-get install ros-kinetic-rosserial 或者sudo git clonegit://github.com/wjwwood/serial.git  (开 ...

  10. PDO中捕获SQL语句中的错误

    使用默认模式-----PDO::ERRMODE_SILENT 在默认模式中设置PDOStatement对象的errorCode属性,但不进行其它不论什么操作. 比如: 通过prepare()和exec ...