题目描述

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

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

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

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

输入

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

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

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

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

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

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

输出

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

样例输入

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

样例输出

3
1
2

提示

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


题解

裸的树链剖分+线段树。

区间修改非常恶心,很多细节。

多写写应该就能好了吧。。。

#include <stdio.h>
#include <algorithm>
using namespace std;
#define lson l , mid , x << 1
#define rson mid + 1 , r , x << 1 | 1
#define N 100005
int fa[N] , deep[N] , si[N] , val[N] , bl[N] , pos[N] , tot;
int head[N] , to[N << 1] , next[N << 1] , cnt;
int sum[N << 2] , lc[N << 2] , rc[N << 2] , mark[N << 2] , n;
char str[10];
void add(int x , int y)
{
to[++cnt] = y;
next[cnt] = head[x];
head[x] = cnt;
}
void dfs1(int x)
{
int i , y;
si[x] = 1;
for(i = head[x] ; i ; i = next[i])
{
y = to[i];
if(y != fa[x])
{
fa[y] = x;
deep[y] = deep[x] + 1;
dfs1(y);
si[x] += si[y];
}
}
}
void dfs2(int x , int c)
{
int k = 0 , i , y;
bl[x] = c;
pos[x] = ++tot;
for(i = head[x] ; i ; i = next[i])
{
y = to[i];
if(fa[x] != y && si[y] > si[k])
k = y;
}
if(k != 0)
{
dfs2(k , c);
for(i = head[x] ; i ; i = next[i])
{
y = to[i];
if(fa[x] != y && y != k)
dfs2(y , y);
}
}
}
void pushup(int x)
{
lc[x] = lc[x << 1];
rc[x] = rc[x << 1 | 1];
sum[x] = sum[x << 1] + sum[x << 1 | 1];
if(rc[x << 1] == lc[x << 1 | 1])
sum[x] -- ;
}
void pushdown(int x)
{
int tmp = mark[x];
mark[x] = 0;
if(tmp)
{
sum[x << 1] = sum[x << 1 | 1] = 1;
lc[x << 1] = rc[x << 1] = lc[x << 1 | 1] = rc[x << 1 | 1] = tmp;
mark[x << 1] = mark[x << 1 | 1] = tmp;
}
}
void update(int b , int e , int v , int l , int r , int x)
{
if(b <= l && r <= e)
{
sum[x] = 1;
lc[x] = rc[x] = v;
mark[x] = v;
return;
}
pushdown(x);
int mid = (l + r) >> 1;
if(b <= mid)
update(b , e , v , lson);
if(e > mid)
update(b , e , v , rson);
pushup(x);
}
void solveupdate(int x , int y , int v)
{
while(bl[x] != bl[y])
{
if(deep[bl[x]] < deep[bl[y]])
{
swap(x , y);
}
update(pos[bl[x]] , pos[x] , v , 1 , n , 1);
x = fa[bl[x]];
}
if(deep[x] > deep[y])
swap(x , y);
update(pos[x] , pos[y] , v , 1 , n , 1);
}
int query(int b , int e , int l , int r , int x)
{
if(b <= l && r <= e)
{
return sum[x];
}
pushdown(x);
int mid = (l + r) >> 1 , ans = 0;
if(b <= mid)
ans += query(b , e , lson);
if(e > mid)
ans += query(b , e , rson);
if(b <= mid && e > mid && rc[x << 1] == lc[x << 1 | 1])
ans -- ;
return ans;
}
int getcl(int p , int l , int r , int x)
{
if(l == r)
return lc[x];
pushdown(x);
int mid = (l + r) >> 1;
if(p <= mid)
return getcl(p , lson);
else
return getcl(p , rson);
}
int solvequery(int x , int y)
{
int ans = 0;
while(bl[x] != bl[y])
{
if(deep[bl[x]] < deep[bl[y]])
swap(x , y);
ans += query(pos[bl[x]] , pos[x] , 1 , n , 1);
if(getcl(pos[bl[x]] , 1 , n , 1) == getcl(pos[fa[bl[x]]] , 1 , n , 1))
ans -- ;
x = fa[bl[x]];
}
if(deep[x] > deep[y])
swap(x , y);
ans += query(pos[x] , pos[y] , 1 , n , 1);
return ans;
}
int main()
{
int i , x , y , z , m;
scanf("%d%d" , &n , &m);
for(i = 1 ; i <= n ; i ++ )
scanf("%d" , &val[i]);
for(i = 1 ; i < n ; i ++ )
{
scanf("%d%d" , &x , &y);
add(x , y);
add(y , x);
}
dfs1(1);
dfs2(1 , 1);
for(i = 1 ; i <= n ; i ++ )
update(pos[i] , pos[i] , val[i] , 1 , n , 1);
while(m -- )
{
scanf("%s" , str);
switch(str[0])
{
case 'C': scanf("%d%d%d" , &x , &y , &z); solveupdate(x , y , z); break;
default: scanf("%d%d" , &x , &y); printf("%d\n" , solvequery(x , y));
}
}
return 0;
}

【bzoj2243】[SDOI2011]染色的更多相关文章

  1. BZOJ2243 SDOI2011 染色 【树链剖分】

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

  2. bzoj2243[SDOI2011]染色 树链剖分+线段树

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

  3. [bzoj2243][SDOI2011]染色

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

  4. BZOJ2243[SDOI2011]染色——树链剖分+线段树

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

  5. [BZOJ2243][SDOI2011]染色 解题报告|树链剖分

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

  6. BZOJ2243 [SDOI2011]染色(树链剖分+线段树合并)

    题目链接 BZOJ2243 树链剖分 $+$ 线段树 线段树每个节点维护$lc$, $rc$, $s$ $lc$代表该区间的最左端的颜色,$rc$代表该区间的最右端的颜色 $s$代表该区间的所有连续颜 ...

  7. BZOJ2243: [SDOI2011]染色(树链剖分/LCT)

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

  8. bzoj2243: [SDOI2011]染色--线段树+树链剖分

    此题代码量较大..但是打起来很爽 原本不用lca做一直wa不知道为什么.. 后来改lca重打了一遍= =结果一遍就AC了orz 题目比较裸,也挺容易打,主要是因为思路可以比较清晰 另:加读入优化比没加 ...

  9. BZOJ2243——[SDOI2011]染色

    1.题目大意:给个树,然后树上每个点都有颜色,然后会有路径的修改,有个询问,询问一条路径上的颜色分成了几段 2.分析:首先这个修改是树剖可以做的,对吧,但是这个分成了几段怎么搞呢,我们的树剖的不是要建 ...

  10. bzoj2243 sdoi2011 染色 paint

    明明是裸树剖 竟然调了这么久好蛋疼 大概是自己比较水的原因吧 顺便+fastio来gangbang #include<iostream> #include<cstring> # ...

随机推荐

  1. TypeScript 素描 - 泛型、枚举

    /* 泛型,好处多多的功能.不过这里最基本的就不打算说了,仅准备说一些 和C#不同的地方 */ /* 泛型接口 GenericIdentityFn 定义了方法的描述等 identity方法则是它的实现 ...

  2. 用DOS命令打开IE浏览器、我的文档等等

    用DOS命令打开IE浏览器 在“start”-运行中直接输入网址就可以了.如输入百度: http://www.baidu.com Command:[ start  http://www.baidu.c ...

  3. Thenao tutorial – indexing

    Theano和numpy一样,支持基本的下标取值方法和高级的下标取值方法. 因为theano中没有boolean类型,所以不支持boolean类型的masks. # head file support ...

  4. 和redis谈一场恋爱(第一天邂逅)

    前几天玩了下Memcache,发现挺好用.知道redis是Memcache的妹妹.我本着大公无私和博大的胸怀,看着redis孤零零的躺在角落里,委实觉得可怜.心里总有个声音在说,你既然已经爱上了Mem ...

  5. IOS中在自定义控件(非视图控制器)的视图跳转中 代理方法与代码块的比较

    //代码块与代替代理的设计方法 我就以在自定义视图中(非视图控制器,不能实现视图控制功能),通过代理和代码块两种方法分别实现视图的跳转,进行对比 首先自定义了一个视图,上面有一个已经注册了得BUtto ...

  6. 什么是FOUC?如何避免FOUC?

    因为在看一些面试题,所以接触到了这个词 FOUC 什么叫做 FOUC 浏览器样式闪烁 如果使用import方法对css进行导入,会导致某些页面在Windows 下的Internet Explorer出 ...

  7. MySQL的mysqldump工具的基本用法

    导出要用到MySQL的mysqldump工具,基本用法是:    shell> mysqldump [OPTIONS] database [tables]    如果你不给定任何表,整个数据库将 ...

  8. echosp 销量排行 新增实际价格

    找到lib_goods.php第147行,代码 $sql = 'SELECT g.goods_id, g.goods_name, g.shop_price,g.goods_thumb, SUM(og. ...

  9. Jquerymobile随笔

    fixed <div data-role="header" data-position="fixed"> <h1>欢迎访问我的主页< ...

  10. centos 7 DenyHosts 安装 防暴力破解ssh登陆

    为了减少软件扫描ssh登陆 还是用这个比较好点  默认端口号22 也要改 登陆密码也不要使用 弱口令 123456 这样的 Description DenyHosts is a python prog ...