题解:

树剖,线段树维护区间颜色段数

记录两端点的颜色,做到O(1)合并

问题:

  非递归建树实现

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=; int n,m;
int incolor[maxn]; int cntedge;
int head[maxn];
int to[maxn<<],nex[maxn<<];
int addedge(int x,int y){
nex[++cntedge]=head[x];
to[cntedge]=y;
head[x]=cntedge;
} int father[maxn],depth[maxn],siz[maxn];
int heavyson[maxn],top[maxn],idx[maxn],ref[maxn]; int dfs1(int now,int fa){
father[now]=fa;
depth[now]=depth[fa]+;
siz[now]=;
for(int i=head[now];i;i=nex[i]){
if(to[i]==fa)continue;
dfs1(to[i],now);
siz[now]+=siz[to[i]];
if(siz[to[i]]>siz[heavyson[now]]){
heavyson[now]=to[i];
}
}
}
int temp;
int dfs2(int now,int toppoint){
top[now]=toppoint;
idx[now]=(++temp);
ref[temp]=now;
if(!heavyson[now])return ;
dfs2(heavyson[now],toppoint);
for(int i=head[now];i;i=nex[i]){
if(to[i]==father[now])continue;
if(to[i]==heavyson[now])continue;
dfs2(to[i],to[i]);
}
} struct SegmentTree{
int l,r;
int lcolor,rcolor;
int setcolor,sum;
}tree[maxn<<];
int pushup(int now){
tree[now].lcolor=tree[now<<].lcolor;
tree[now].rcolor=tree[now<<|].rcolor;
if(tree[now<<].rcolor==tree[now<<|].lcolor){
tree[now].sum=tree[now<<].sum+tree[now<<|].sum-;
}else{
tree[now].sum=tree[now<<].sum+tree[now<<|].sum;
}
}
int pushdown(int now){
if(tree[now].setcolor!=-){
tree[now<<].setcolor=tree[now<<].lcolor=tree[now<<].rcolor=tree[now].setcolor;
tree[now<<|].setcolor=tree[now<<|].lcolor=tree[now<<|].rcolor=tree[now].setcolor;
tree[now<<].sum=tree[now<<|].sum=;
tree[now].setcolor=-;
}
} int Build(int now,int l,int r){
tree[now].l=l;tree[now].r=r;
tree[now].setcolor=-;
if(l==r){
tree[now].lcolor=tree[now].rcolor=incolor[ref[l]];
tree[now].sum=;
return ;
}
int mid=(l+r)>>;
Build(now<<,l,mid);
Build(now<<|,mid+,r);
pushup(now);
} int Updata(int now,int ll,int rr,int x){
if(tree[now].l>=ll&&tree[now].r<=rr){
tree[now].setcolor=tree[now].lcolor=tree[now].rcolor=x;
tree[now].sum=;
return ;
}
int mid=(tree[now].l+tree[now].r)>>;
pushdown(now);
if(ll<=mid)Updata(now<<,ll,rr,x);
if(rr>mid)Updata(now<<|,ll,rr,x);
pushup(now);
} int Querysum(int now,int ll,int rr){
if(tree[now].l>=ll&&tree[now].r<=rr){
return tree[now].sum;
}
int mid=(tree[now].l+tree[now].r)>>;
pushdown(now);
if(rr<=mid)return Querysum(now<<,ll,rr);
else if(ll>mid)return Querysum(now<<|,ll,rr);
else if(tree[now<<].rcolor==tree[now<<|].lcolor)return Querysum(now<<,ll,rr)+Querysum(now<<|,ll,rr)-;
else return Querysum(now<<,ll,rr)+Querysum(now<<|,ll,rr);
} int Querycolor(int now,int p){
if(tree[now].l==tree[now].r){
return tree[now].lcolor;
}
int mid=(tree[now].l+tree[now].r)>>;
pushdown(now);
if(p<=mid)return Querycolor(now<<,p);
else return Querycolor(now<<|,p);
} int Change(int u,int v,int x){
int tu=top[u];
int tv=top[v];
while(tu!=tv){
if(depth[tu]<depth[tv]){
swap(tu,tv);swap(u,v);
}
Updata(,idx[tu],idx[u],x);
u=father[tu];tu=top[u];
}
if(depth[u]>depth[v])swap(u,v);
Updata(,idx[u],idx[v],x);
} int Getans(int u,int v){
int ret=;
int tu=top[u];
int tv=top[v];
while(tu!=tv){
if(depth[tu]<depth[tv]){
swap(tu,tv);swap(u,v);
}
ret=ret+Querysum(,idx[tu],idx[u]);
u=father[tu];
if(Querycolor(,idx[u])==Querycolor(,idx[tu]))--ret;
tu=top[u];
}
if(depth[u]>depth[v])swap(u,v);
ret=ret+Querysum(,idx[u],idx[v]);
return ret;
} int minit(){
temp=cntedge=;
memset(heavyson,,sizeof(heavyson));
memset(head,,sizeof(head));
} int main(){
scanf("%d%d",&n,&m);
minit(); for(int i=;i<=n;++i)scanf("%d",&incolor[i]);
for(int i=;i<=n-;++i){
int x,y;
scanf("%d%d",&x,&y);
addedge(x,y);addedge(y,x);
}
dfs1(,);
dfs2(,);
Build(,,n); char opty[];
while(m--){
int x,y,z;
scanf("%s",opty);
if(opty[]=='C'){
scanf("%d%d%d",&x,&y,&z);
Change(x,y,z);
}else{
scanf("%d%d",&x,&y);
printf("%d\n",Getans(x,y));
}
}
return ;
}

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. linuxshell命令学习1——用户、文件和目录操作

    1.cmd(command) --help #查找这个命令相关的帮助 2.切换用户 2.1 sudo 让普通用户可以执行root命令,暂时切换到超级用户(root)用户模式 2.1.1 su  切换到 ...

  2. 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:接口的基本实现

    interface A{ // 定义接口A public static final String AUTHOR = "李兴华" ; // 全局常量 public abstract ...

  3. python-python基础2

    本章内容: 1.列表.元组 2.字典 3.集合 4.文件操作 5.字符编码与转码 一.列表.元组操作 列表是我们最以后最常用的数据类型之一,通过列表可以对数据实现最方便的存储.修改等操作 names= ...

  4. 设备树DTS 学习:4-编写实战

    背景 讲完设备树的有关概念以及语法以后,我们接下来就让 我们的驱动 使用 设备树. ref : <内核学习笔记14:内核设备树学习>.<u-boot对设备树的支持> 测试代码 ...

  5. SelectList类的构造函数

    SelectList类的构造函数 2016年05月23日 17:29:52 FrankyJson 阅读数 272 标签: MVC函数 更多 个人分类: MVC   SelectList 构造函数 (I ...

  6. es678910语法糖

    傲娇: 新es是js的进步,是编程的进步,es6已经过去了5年了,兼容率达到了90%,还是有10%的手机不兼容,那到底应不应该去照顾那些跟不上的人,我觉得是不应该的,新es能5行写出来的功能,我为什么 ...

  7. Day7 - J - Raising Modulo Numbers POJ - 1995

    People are different. Some secretly read magazines full of interesting girls' pictures, others creat ...

  8. linux 查看ip、用户、时间对应执行的命令

    这个需要使用到history命令.可以加数字,返回最近执行的几条命令.如果不加数字会返回所有的历史命令. [root@localhost ~]# history 20 1015 rm stdin.lo ...

  9. JDK8中的HashMap实现原理及源码分析

    大纲 一.什么是Hash?什么是HashMap? 二.HashMap的内部实现机制 1.HashMap基本元素 ①DEFAULT_INITIAL_CAPACITY&MAXIMUM_CAPACI ...

  10. 008.Oracle数据库 , 判断字段内容是否为空

    /*Oracle数据库查询日期在两者之间*/ SELECT PKID, OCCUR_DATE, ATA FROM LM_FAULT WHERE ( ( OCCUR_DATE >= to_date ...