2243: [SDOI2011]染色

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 4637  Solved: 1726
[Submit][Status][Discuss]

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,表示xy之间有一条无向边。

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

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

Source

【思路】

树链剖分,线段树

线段树维护lc rc c s分别表示线段的左右端颜色 update设置颜色 线段所含颜色数,需要注意的是线段合并以及统计信息时候需要考虑两线段接点是否重色。

Ps:dep比较的是top,T-T    节点信息加上lr倒是个不错的写法 :)

【代码】

 #include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
#include<algorithm>
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; const int N = 1e5+1e5+; struct Node {
int l,r,lc,rc,c,s;
}T[N<<];
vector<int> G[N];
int n,m,z,c[N];
char s[]; int w[N],top[N],son[N],siz[N],fa[N],dep[N]; void dfs1(int u) {
siz[u]=; son[u]=;
for(int i=;i<G[u].size();i++) {
int v=G[u][i];
if(v!=fa[u]) {
fa[v]=u; dep[v]=dep[u]+;
dfs1(v);
if(siz[v]>siz[son[u]]) son[u]=v;
siz[u]+=siz[v];
}
}
}
void dfs2(int u,int tp) {
w[u]=++z; top[u]=tp;
if(son[u]) dfs2(son[u],tp);
for(int i=;i<G[u].size();i++) {
int v=G[u][i];
if(v!=son[u] && v!=fa[u]) dfs2(v,v);
}
}
void pushdown(int u) {
if(T[u].c!=- && T[u].l<T[u].r) {
int lc=u<< , rc=lc|;
T[lc].c=T[rc].c=T[u].c;
T[lc].lc=T[lc].rc=T[rc].lc=T[rc].rc=T[u].c;
T[lc].s=T[rc].s=;
T[u].c=-;
}
}
void maintain(int u) {
int lc=u<<,rc=lc|;
T[u].lc=T[lc].lc , T[u].rc=T[rc].rc;
T[u].s=T[lc].s+T[rc].s-(T[lc].rc==T[rc].lc);
}
void build(int u,int L,int R) {
T[u].l=L , T[u].r=R , T[u].c=- , T[u].s=;
if(L==R) return ;
int M=(L+R)>>;
build(u<<,L,M) , build(u<<|,M+,R);
}
void update(int u,int L,int R,int x) {
pushdown(u);
if(L==T[u].l && R==T[u].r) { //CC
T[u].c=T[u].lc=T[u].rc=x;
T[u].s=; return ;
}
int M=(T[u].l+T[u].r)>> , lc=u<< , rc=lc|;
if(R<=M) update(lc,L,R,x); //can change
else if(L>M) update(rc,L,R,x);
else
update(lc,L,M,x) , update(rc,M+,R,x);
maintain(u);
}
int query(int u,int L,int R) {
pushdown(u);
if(L==T[u].l && R==T[u].r) return T[u].s;
int M=(T[u].l+T[u].r)>> , lc=u<< , rc=lc|;
if(R<=M) return query(lc,L,R);
else if(L>M) return query(rc,L,R);
else
return query(lc,L,M)+query(rc,M+,R)-(T[lc].rc==T[rc].lc);
}
int find(int u,int r) {
pushdown(u);
if(T[u].l==T[u].r) return T[u].lc;
int M=(T[u].l+T[u].r)>>;
return r<=M? find(u<<,r):find(u<<|,r);
}
void modify(int u,int v,int x) {
while(top[u]!=top[v]) {
if(dep[top[u]]<dep[top[v]]) swap(u,v);
update(,w[top[u]],w[u],x);
u=fa[top[u]];
}
if(dep[u]>dep[v]) swap(u,v);
update(,w[u],w[v],x);
}
int ask(int u,int v) {
int ans=;
while(top[u]!=top[v]) {
if(dep[top[u]]<dep[top[v]]) swap(u,v);
ans+=query(,w[top[u]],w[u]);
if(find(,w[fa[top[u]]])==find(,w[top[u]])) ans--;
u=fa[top[u]];
}
if(dep[u]>dep[v]) swap(u,v);
ans+=query(,w[u],w[v]);
return ans;
} void read(int& x) {
char c=getchar();
while(!isdigit(c)) c=getchar();
x=;
while(isdigit(c))
x=x*+c-'' , c=getchar();
}
int main() {
read(n) , read(m);
FOR(i,,n) read(c[i]);
int u,v,k;
FOR(i,,n-) {
read(u) , read(v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs1() , dfs2(,);
build(,,n);
FOR(i,,n) update(,w[i],w[i],c[i]);
while(m--) {
scanf("%s",s);
read(u) , read(v);
if(s[]=='C')
read(k) , modify(u,v,k);
else
printf("%d\n",ask(u,v));
}
return ;
}

bzoj 2243 [SDOI2011]染色(树链剖分,线段树)的更多相关文章

  1. 2243: [SDOI2011]染色 树链剖分+线段树染色

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

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

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

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

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

  4. B20J_2243_[SDOI2011]染色_树链剖分+线段树

    B20J_2243_[SDOI2011]染色_树链剖分+线段树 一下午净调这题了,争取晚上多做几道. 题意: 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成 ...

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

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

  6. BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )

    BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...

  7. BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)

    BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...

  8. BZOJ 3672[NOI2014]购票(树链剖分+线段树维护凸包+斜率优化) + BZOJ 2402 陶陶的难题II (树链剖分+线段树维护凸包+分数规划+斜率优化)

    前言 刚开始看着两道题感觉头皮发麻,后来看看题解,发现挺好理解,只是代码有点长. BZOJ 3672[NOI2014]购票 中文题面,题意略: BZOJ 3672[NOI2014]购票 设f(i)f( ...

  9. bzoj 4196 [Noi2015]软件包管理器 (树链剖分+线段树)

    4196: [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 2852  Solved: 1668[Submit][Sta ...

  10. bzoj 2157: 旅游【树链剖分+线段树】

    裸的树链剖分+线段树 但是要注意一个地方--我WA了好几次才发现取完相反数之后max值和min值是要交换的-- #include<iostream> #include<cstdio& ...

随机推荐

  1. SGU 260.Puzzle (异或高斯消元)

    题意: 有n(<200)个格子,只有黑白两种颜色.可以通过操作一个格子改变它和其它一些格子的颜色.给出改变的关系和n个格子的初始颜色,输出一种操作方案使所有格子的颜色相同. Solution: ...

  2. jQuery EasyUI tree中state属性慎用

    EasyUI 1.4.4 tree控件中,如果是叶子节点,切忌把state设置为closed,否则该节点会加载整个tree,形成死循环 例如: json入下: [ { "checked&qu ...

  3. php类的方法

    方法就是在类中的function,很多时候我们分不清方法与函数有什么差别,在面向过程的程序设计中function叫做函数,在面向对象中function则被称之为方法. 同属性一样,类的方法也具有pub ...

  4. phpcms V9 首页模板文件解析(转)

    转自:http://www.cnblogs.com/Braveliu/p/5100018.html 转在了解了<phpcms V9 URL访问解析>之后,我们已经知道首页最终执行的是con ...

  5. CentOS6.6源码编译升级GCC至4.8.2

    升级前提 源码编译需要至少要有一个可用的gcc编译器. 可以用过yum自动安装或者手动下载rpm包安装. 通过yum可以看到至少需要下面这些安装包,所以可以到许多rpm package站点中搜索下载相 ...

  6. js截取小数点后几位的写法

    截取小数点后几位的方法有很多,下面为大家介绍下使用js是如何实现的 如果${showInfo.tt}的值为20,要要它除以10以后精确到小数点后2位,那么js代码中可作如下写法:  复制代码 代码如下 ...

  7. Nginx+uWSGI+Django+Python在Linux上的部署

    搞了一整天,终于以发现自己访问网络的端口是错误的结束了. 首先要安装Nginx,uWSGI,Django,Python,这些都可以再网上查到. 安装好后可以用 whereis 命令查看是否安装好了各种 ...

  8. C的快速趋向实验 -->

    今天刚学到C的一个新玩法,非常有意思,叫趋向于,写作“-->”,比如说如果要实现一个倒数的程序,我们可以定义一个变量 counter,然后让它趋向于0... #include <stdio ...

  9. zend studio 9.0.4 安装破解

    转载于 http://www.geekso.com/ZendStudio9-key 注册破解步骤第一步:如果已经安装过Zend Studio 9.0.4的,请打开Zend Studio 9.0.4,在 ...

  10. [转]jquery.timer用法

    转自:http://www.cnblogs.com/guohui/archive/2012/02/24/2366668.html 来自JavaEye论坛的JQuery Timers应用知识 jQuer ...