Description

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

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

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

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

Input

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

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

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

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

$”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,M\;\leq\;10^5,c\;\in\;z,c\;\in\;[0, 10^9]$. 

Solution

树链剖分+线段树.

每次上移的时候判断相邻两段端点是否同色即可.

#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 100005
#define M 300005
using namespace std;
struct linetree{
int l,r,lc,rc,cnt;
}lt[M];
struct graph{
int nxt,to;
}e[M];
char c[2];
int g[N],a[N],w[N],n,m,u,v,k,l,cnt;
int f[N],p[N],dep[N],siz[N],son[N],top[N];
inline void addedge(int x,int y){
e[++cnt].nxt=g[x];g[x]=cnt;e[cnt].to=y;
}
inline void dfs1(int u){
int m=0;siz[u]=1;
for(int i=g[u];i;i=e[i].nxt)
if(!dep[e[i].to]){
f[e[i].to]=u;
dep[e[i].to]=dep[u]+1;
dfs1(e[i].to);
siz[u]+=siz[e[i].to];
if(siz[e[i].to]>m){
son[u]=e[i].to;
m=siz[e[i].to];
}
}
}
inline void dfs2(int u,int tp){
top[u]=tp;p[u]=++cnt;w[cnt]=a[u];
if(son[u]) dfs2(son[u],tp);
for(int i=g[u];i;i=e[i].nxt)
if(f[u]!=e[i].to&&e[i].to!=son[u])
dfs2(e[i].to,e[i].to);
}
inline void build(int u,int l,int r){
lt[u].l=l;lt[u].r=r;
if(lt[u].l<lt[u].r){
int lef=u<<1,rig=u<<1|1;
int mid=(lt[u].l+lt[u].r)>>1;
build(lef,l,mid);build(rig,mid+1,r);
lt[u].cnt=lt[lef].cnt+lt[rig].cnt;
if(lt[lef].rc==lt[rig].lc) --lt[u].cnt;
lt[u].lc=lt[lef].lc;lt[u].rc=lt[rig].rc;
}
else{
lt[u].cnt=1;lt[u].lc=lt[u].rc=w[lt[u].l];
}
}
inline void cover(int u,int l,int r,int k){
if(lt[u].l>=l&&lt[u].r<=r){
lt[u].lc=lt[u].rc=k;lt[u].cnt=1;
}
else if(lt[u].l<lt[u].r){
int lef=u<<1,rig=u<<1|1;
int mid=(lt[u].l+lt[u].r)>>1;
if(lt[u].cnt==1){
lt[lef].cnt=lt[rig].cnt=1;
lt[lef].lc=lt[lef].rc=lt[rig].lc=lt[rig].rc=lt[u].lc;
}
if(l<=mid) cover(lef,l,r,k);
if(r>mid) cover(rig,l,r,k);
lt[u].cnt=lt[lef].cnt+lt[rig].cnt;
if(lt[lef].rc==lt[rig].lc) --lt[u].cnt;
lt[u].lc=lt[lef].lc;lt[u].rc=lt[rig].rc;
}
}
inline int ask(int u,int l,int r){
if(lt[u].l>=l&&lt[u].r<=r)
return lt[u].cnt;
if(lt[u].l<lt[u].r){
int lef=u<<1,rig=u<<1|1,ret=0;
int mid=(lt[u].l+lt[u].r)>>1;
if(lt[u].cnt==1){
lt[lef].cnt=lt[rig].cnt=1;
lt[lef].lc=lt[rig].lc=lt[lef].rc=lt[rig].rc=lt[u].lc;
}
if(l<=mid) ret+=ask(lef,l,r);
if(r>mid) ret+=ask(rig,l,r);
if(l<=mid&&r>mid&&lt[lef].rc==lt[rig].lc) --ret;
return ret;
}
}
inline int col(int u,int x){
if(lt[u].l==x) return lt[u].lc;
if(lt[u].r==x) return lt[u].rc;
if(lt[u].l<lt[u].r){
int lef=u<<1,rig=u<<1|1;
int mid=(lt[u].l+lt[u].r)>>1;
if(lt[u].cnt==1){
lt[lef].cnt=lt[rig].cnt=1;
lt[lef].lc=lt[rig].lc=lt[lef].rc=lt[rig].rc=lt[u].lc;
}
if(x<=mid) return col(lef,x);
return col(rig,x);
}
}
inline void cov(int x,int y,int k){
int t;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){
t=x;x=y;y=t;
}
cover(1,p[top[x]],p[x],k);
x=f[top[x]];
}
if(p[x]>p[y]){
t=x;x=y;y=t;
}
cover(1,p[x],p[y],k);
}
inline int q(int x,int y){
int ret=0,t;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){
t=x;x=y;y=t;
}
ret+=ask(1,p[top[x]],p[x]);
if(col(1,p[top[x]])==col(1,p[f[top[x]]])) --ret;
x=f[top[x]];
}
if(p[x]>p[y]){
t=x;x=y;y=t;
}
ret+=ask(1,p[x],p[y]);
return ret;
}
inline int lca(int x,int y){
int t;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){
t=x;x=y;y=t;
}
x=f[top[x]];
}
if(p[x]>p[y]){
t=x;x=y;y=t;
}
return x;
}
inline void Aireen(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
for(int i=1,x,y;i<n;++i){
scanf("%d%d",&x,&y);
addedge(x,y);addedge(y,x);
}
dep[1]=1;dfs1(1);
cnt=0;dfs2(1,1);
build(1,1,n);
while(m--){
scanf("%s%d%d",c,&u,&v);
if(c[0]=='C'){
scanf("%d",&k);cov(u,v,k);
}
else{
l=lca(u,v);
printf("%d\n",q(u,v));
}
}
}
int main(){
freopen("color.in","r",stdin);
freopen("color.out","w",stdout);
Aireen();
fclose(stdin);
fclose(stdout);
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]染色——树链剖分+线段树

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

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

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

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

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

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

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

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

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

  8. BZOJ2243——[SDOI2011]染色

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

  9. bzoj2243 sdoi2011 染色 paint

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

随机推荐

  1. jquery noConflict详解

    noConflict是防止其他库也用了$作为全局变量而引起的冲突,我们看看jquery是怎么做的 首先jquery在代码的开始部分定义了2个私有变量: _jQuery = window.jQuery ...

  2. cocoapod

    更新代码: sudo gem install -n /usr/local/bin cocoapods --pre ex: The dependency `` is not used in any co ...

  3. 003商城项目:数据库的创建以及ssm框架的整合

    我们创建一个数据库.如下: 然后开始整合框架:  先给出整合框架的思路: 我们的Dao层用的是Mybatis,其实Mybatis与Spring整合要做的就是把他的数据库连接这部分全部交给Spring来 ...

  4. 高端黑链SEO—恶意JS脚本注入访问伪随机域名

    摘要:我们的服务器又出入侵事故了.有客户的 html 网页底部被插入了一段 js 脚本,导致访客打开网页时被杀毒软件警告网站上有恶意代码.在黑链 SEO 中这是常见的手法,但奇特的地方就在于我们这次捕 ...

  5. Linux 网络编程详解六(多进程服务器僵尸进程解决方案)

    小结:在点对点p2p程序中,服务器端子程序退出,子进程会主动发送信号,关闭父进程,但是这种模式导致服务器只能支持一个客户端连接,本章节中使用新的框架,子进程退出,不主动发送信号关闭父进程,而是父进程安 ...

  6. SQL Server 用SSMS查看依赖关系有时候不准确,改用代码查

    SQL Server 用SSMS查看依赖关系有时候不准确,明明某个sp中有用到表tohen,查看表tohen的依赖关系的时候,却看不到这个sp 用代码查看方式如下: --依赖于表tohen的对象 SE ...

  7. weblogic.nodemanager.common.ConfigException: Native version is enabled but nodemanager native library could not be loaded 解决办法

    近日在一个原本工作正常的weblogic web server(操作系统为redhat 64位系统)上折腾安装redis/hadoop等东东,yum install了一堆第3方类库后,重启weblog ...

  8. IntelliJ IDEA 13试用手记(附详细截图)

    从去年开始转java以来,一直在寻找一款趁手的兵器,eclipse虽然是很多java程序员的首选,但是我发现一旦安装了一些插件,workspace中的项目达到数10个以后,经常崩溃,实在影响编程的心情 ...

  9. C# 调用一个按钮的Click事件(利用反射)

    最基本的调用方法 (1)button1.PerformClick();(2)button1_Click(null,null);(3)button_Click(null,new EventArgs()) ...

  10. C++ redirect input

    #include<iostream> #include<string> #include<fstream> using namespace std; int mai ...