Description

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

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

2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),

如“112221”由3段组成:“11”、“222”和“1”。

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

Input

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

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

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

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

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

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

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<=105,操作数M<=105,所有的颜色C为整数且在[0, 10^9]之间。

Solution

这题有很多做法,树剖,LCT

因为现在正在练LCT,所以就用LCT写了

一条链上,维护四个东西,col(结点本身颜色),lco(结点包括其Splay子树代表的一段颜色的最左边颜色),rco(这个就是最右边的),sum(结点包括其Splay子树代表的一段的答案)

因为LCT的Splay保证了中序遍历按深度递增,所以一个结点包括其子树后包含的位置一定是连续的一段,所以可以这样维护

然后对于pushup

首先直接把两个儿子的sum与自己的长度1全部加上后

再判断连接的地方是否相同,如果相同就减去多加的(这个地方可能说不清楚,但一看代码就明白了)

然后当前结点的lco就是左儿子的lco,rco就是右儿子的rco

还要注意如果没有左右儿子,就千万不要转移,否则会出问题,lco和rco会转移错误

#include<bits/stdc++.h>
#define ll long long
#define db double
#define ld long double
const int MAXN=100000+10;
int n,m;
#define lc(x) ch[(x)][0]
#define rc(x) ch[(x)][1]
struct LCT{
int ch[MAXN][2],fa[MAXN],rev[MAXN],sum[MAXN],lco[MAXN],rco[MAXN],pnt[MAXN],stack[MAXN],cnt,col[MAXN];
inline bool nroot(int x)
{
return lc(fa[x])==x||rc(fa[x])==x;
}
inline void reverse(int x)
{
std::swap(lc(x),rc(x));
std::swap(lco[x],rco[x]);
rev[x]^=1;
}
inline void paint(int x,int c)
{
sum[x]=1;
pnt[x]=col[x]=lco[x]=rco[x]=c;
}
inline void pushup(int x)
{
sum[x]=sum[lc(x)]+sum[rc(x)]+1;
if(lc(x)&&rc(x))sum[x]=sum[x]-(rco[lc(x)]==col[x])-(col[x]==lco[rc(x)]);
else if(lc(x))sum[x]=sum[x]-(rco[lc(x)]==col[x]);
else if(rc(x))sum[x]=sum[x]-(col[x]==lco[rc(x)]);
lco[x]=rco[x]=col[x];
if(lc(x))lco[x]=lco[lc(x)];
if(rc(x))rco[x]=rco[rc(x)];
}
inline void pushdown(int x)
{
if(pnt[x])
{
if(lc(x))paint(lc(x),pnt[x]);
if(rc(x))paint(rc(x),pnt[x]);
pnt[x]=0;
}
if(rev[x])
{
if(lc(x))reverse(lc(x));
if(rc(x))reverse(rc(x));
rev[x]=0;
}
}
inline void rotate(int x)
{
int f=fa[x],p=fa[f],c=(rc(f)==x);
if(nroot(f))ch[p][rc(p)==f]=x;
fa[ch[f][c]=ch[x][c^1]]=f;
fa[ch[x][c^1]=f]=x;
fa[x]=p;
pushup(f);
pushup(x);
}
inline void splay(int x)
{
cnt=0;
stack[++cnt]=x;
for(register int i=x;nroot(i);i=fa[i])stack[++cnt]=fa[i];
while(cnt)pushdown(stack[cnt--]);
for(register int y=fa[x];nroot(x);rotate(x),y=fa[x])
if(nroot(y))rotate((lc(y)==x)==(lc(fa[y])==y)?y:x);
pushup(x);
}
inline void access(int x)
{
for(register int y=0;x;x=fa[y=x])splay(x),rc(x)=y,pushup(x);
}
inline void makeroot(int x)
{
access(x);splay(x);reverse(x);
}
inline void split(int x,int y)
{
makeroot(x);access(y);splay(y);
}
inline void link(int x,int y)
{
makeroot(x);fa[x]=y;
}
};
LCT T;
#undef lc
#undef rc
inline void read(int &x)
{
int data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=(data<<3)+(data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
inline void write(int x,char c='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(c!='\0')putchar(c);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
int main()
{
read(n);read(m);
for(register int i=1;i<=n;++i)
{
int color;
read(color);
T.col[i]=T.lco[i]=T.rco[i]=color;
T.sum[i]=1;
}
for(register int i=1;i<n;++i)
{
int u,v;
read(u);read(v);
T.link(u,v);
}
while(m--)
{
char opt[2];
scanf("%s",opt);
if(opt[0]=='C')
{
int a,b,c;
read(a);read(b);read(c);
T.split(a,b);T.paint(b,c);
}
if(opt[0]=='Q')
{
int a,b;
read(a);read(b);
T.split(a,b);
write(T.sum[b],'\n');
}
}
return 0;
}

【刷题】BZOJ 2243 [SDOI2011]染色的更多相关文章

  1. BZOJ 2243: [SDOI2011]染色 [树链剖分]

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6651  Solved: 2432[Submit][Status ...

  2. bzoj 2243 [SDOI2011]染色(树链剖分,线段树)

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 4637  Solved: 1726[Submit][Status ...

  3. Bzoj 2243: [SDOI2011]染色 树链剖分,LCT,动态树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 5020  Solved: 1872[Submit][Status ...

  4. bzoj 2243: [SDOI2011]染色 线段树区间合并+树链剖分

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 7925  Solved: 2975[Submit][Status ...

  5. bzoj 2243: [SDOI2011]染色 (树链剖分+线段树 区间合并)

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 9854  Solved: 3725[Submit][Status ...

  6. BZOJ 2243: [SDOI2011]染色 树链剖分 倍增lca 线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  7. BZOJ 2243: [SDOI2011]染色 树链剖分+线段树区间合并

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

  8. bzoj 2243 [SDOI2011]染色(树链剖分+线段树合并)

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

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

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

  10. BZOJ 2243 [SDOI2011]染色 (树链剖分)(线段树区间修改)

    [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6870  Solved: 2546[Submit][Status][Disc ...

随机推荐

  1. sketch 相关论文

    sketch 相关论文 Sketch Simplification We present a novel technique to simplify sketch drawings based on ...

  2. MYSQL数据库与Emoji表情的故事

    问题背景 手机上众多输入法和键盘支持输入 emoji 表情,给早期设计的程序造成了越来越多的干扰. 移动端购物的流行,2018 年 "双十一"全网移动端交易达到 93.6% 微信年 ...

  3. 利用jsencrypt 做非对称加密

    1.生成 private key openssl genrsa -out rsa_1024_priv.pem 1024 2.生成public key openssl rsa -pubout -in r ...

  4. Protocol buffer的使用案例

    Protocolbuffer(以下简称PB)是google 的一种数据交换的格式,它独立于语言,独立于平台.google 提供了多种语言的实现:java.c#.c++.go 和 python,每一种实 ...

  5. centos7.6 安装配置rabbitmq

    IP地址:192.168.200.108 安装erlang 和 依赖环境 yum install -y socat yum install -y erlang 安装rabbitmq yum insta ...

  6. python—索引与切片总结

    python中索引与切片的熟练掌握对于字符串的操作很有帮助,梳理如下: (1)索引 S = 'hello world' 1)正向索引 正向索引从0开始,向右依次递增. 2)反向索引 反向索引从-1开始 ...

  7. 关于java内存泄露的总结--引用的类型:强引用,弱引用,软引用

    今天面试了一家公司的java开发方面的实习生,被问到一个问题:如何处理java中的内存泄露问题,保证java的虚拟机内存不会被爆掉,当时其实觉得面试官的问题有点泛,所以也没有很好领会他的意思,答案也不 ...

  8. 第一章 HTML介绍

    1.1 Html和CSS的关系 学习web前端开发基础技术需要掌握:HTML.CSS.JavaScript语言.下面我们就来了解下这三门技术都是用来实现什么的: 1. HTML是网页内容的载体.内容就 ...

  9. java实验三 敏捷开发与XP实践

    一.实验内容 (一)敏捷开发与XP 软件开发流程的目的是为了提高软件开发.运营.维护的效率,并提高软件的质量.用户满意度.可靠性和软件的可维护性. 光有各种流程的思想是不够的,我们还要有一系列的工具来 ...

  10. 20162328蔡文琛week08

    学号 20162328 <程序设计与数据结构>第X周学习总结 教材学习内容总结 错误和异常代表不常见的或不正确处理的对象. 抛出异常时输出的消息提供了方法调用栈的轨迹. 每个catch子句 ...