【树链剖分】bzoj2243 [SDOI2011]染色
树链剖分模板题。线段树维护每个段中的颜色数、左端点颜色、右端点颜色。
#include<cstdio>
#include<algorithm>
using namespace std;
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define maxn 100001
int col[maxn<<],L[maxn<<],R[maxn<<],delta[maxn<<],n,m,Val[maxn],Num[maxn];
int V[maxn<<],First[maxn<<],Next[maxn<<],All_Lcol,All_Rcol,en;
bool vis[maxn];
int top[maxn],son[maxn],tot,dep[maxn],fa[maxn],siz[maxn],Map[maxn];
inline void AddEdge(const int &UU,const int &VV){V[++en]=VV;Next[en]=First[UU];First[UU]=en;}
inline void pushup(const int &rt)
{
L[rt]=L[rt<<];
R[rt]=R[rt<<|];
col[rt]=col[rt<<]+col[rt<<|]-(R[rt<<]==L[rt<<|]);
}
inline void pushdown(const int &rt)
{
if(delta[rt]!=-)
{
L[rt<<]=R[rt<<]=L[rt<<|]=R[rt<<|]=delta[rt];
delta[rt<<]=delta[rt<<|]=delta[rt];
delta[rt]=-;
col[rt<<]=col[rt<<|]=;
}
}
void buildtree(int rt,int l,int r)
{
delta[rt]=-;
if(l==r)
{
col[rt]=;
L[rt]=R[rt]=Val[Map[l]];//l是线段树中的新位置,
//Map[l]表示新位置对应的在树中的编号是谁
return;
}
int m=l+r>>;
buildtree(lson);
buildtree(rson);
pushup(rt);
}
void update(int ql,int qr,int v,int rt,int l,int r)
{
if(ql<=l&&r<=qr)
{
delta[rt]=L[rt]=R[rt]=v;//更新当前结点的标记值
col[rt]=;
return;
}
pushdown(rt);//将该节点的标记下传到孩子们
int m=l+r>>;
if(ql<=m)
update(ql,qr,v,lson);
if(m<qr)
update(ql,qr,v,rson);
pushup(rt);
}
int query(int ql,int qr,int rt,int l,int r)
{
if(ql==l)
All_Lcol=L[rt];
if(r==qr)
All_Rcol=R[rt];
if(ql<=l&&r<=qr)
return col[rt];
pushdown(rt);//将该节点的标记下传到孩子们
int m=l+r>>,res=,now1=-,now2=-;
if(ql<=m)
{
res+=query(ql,qr,lson);
now1=R[rt<<];
}
if(m<qr)
{
res+=query(ql,qr,rson);
now2=L[rt<<|];
}
res-=(now1==now2 && now1!=-);
return res;
}
inline void Update(int u,int v,int val)
{
int f1=top[u],f2=top[v];
while(f1!=f2)
{
if(dep[f1]<dep[f2])
{
swap(u,v);
swap(f1,f2);
}
update(Num[f1],Num[u],val,,,n);
u=fa[f1];
f1=top[u];
}
if(dep[u]<dep[v])
swap(u,v);
update(Num[v],Num[u],val,,,n);
}
inline int Query(int u,int v)
{
int f1=top[u],f2=top[v],ans=,t1=-,t2=-;
while(f1!=f2)
{
if(dep[f1]<dep[f2])
{
swap(u,v);
swap(f1,f2);
swap(t1,t2);
}
ans+=query(Num[f1],Num[u],,,n);
ans-=(t1==All_Rcol);
t1=All_Lcol;
u=fa[f1];
f1=top[u];
}
if(dep[u]<dep[v])
{
swap(u,v);
swap(t1,t2);
}
ans+=query(Num[v],Num[u],,,n);
ans-=((t1==All_Rcol&&t1!=-)+(t2==All_Lcol&&t2!=-));
return ans;
}
void dfs1(int cur,int father,int depth)
{
fa[cur]=father;
dep[cur]=depth;
siz[cur]=;
for(int i=First[cur];i;i=Next[i])
if(!vis[V[i]])
{
vis[V[i]]=true;
dfs1(V[i],cur,depth+);
siz[cur]+=siz[V[i]];
if(siz[V[i]]>siz[son[cur]])
son[cur]=V[i];
vis[V[i]]=false;
}
}
void dfs2(int cur)
{
if(son[cur]&&!vis[son[cur]])
{
vis[son[cur]]=true;
top[son[cur]]=top[cur];
Num[son[cur]]=++tot;
Map[tot]=son[cur];
dfs2(son[cur]);
vis[son[cur]]=false;
}
for(int i=First[cur];i;i=Next[i])
if(son[cur]!=V[i]&&!vis[V[i]])
{
vis[V[i]]=true;
top[V[i]]=V[i];
Num[V[i]]=++tot;
Map[tot]=V[i];
dfs2(V[i]);
vis[V[i]]=false;
}
}
int Res,num;
char C;
char CH[];
inline int getint()
{
Res=;
C='*';
while(C<''||C>'')
C=getchar();
while(C>=''&&C<='')
{
Res=Res*+(C-'');
C=getchar();
}
return Res;
}
inline void putint(int x)
{
num=;
while(x>)
CH[++num]=x%,x/=;
while(num)
putchar(CH[num--]+);
putchar('\n');
}
int main()
{
int x,y,a,b,c;
char op;
n=getint();
m=getint();
for(int i=;i<=n;i++)
Val[i]=getint();
for(int i=;i<n;i++){x=getint();y=getint();AddEdge(x,y);AddEdge(y,x);}
top[]=;
Num[]=++tot;
Map[tot]=;
vis[]=true;
dfs1(,,);
dfs2();
buildtree(,,n);
for(int i=;i<=m;i++)
{
getchar();
op=getchar();
a=getint();
b=getint();
if(op=='C')
{
c=getint();
Update(a,b,c);
}
else
putint(Query(a,b));
}
return ;
}
【树链剖分】bzoj2243 [SDOI2011]染色的更多相关文章
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- bzoj-2243 2243: [SDOI2011]染色(树链剖分)
题目链接: 2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6267 Solved: 2291 Descript ...
- bzoj2243[SDOI2011]染色 树链剖分+线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 9012 Solved: 3375[Submit][Status ...
- BZOJ2243 洛谷2486 [SDOI2011]染色 树链剖分
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2243 题目传送门 - 洛谷2486 题意概括 一棵树,共n个节点. 让你支持以下两种操作,共m次操 ...
- BZOJ2243 SDOI2011 染色 【树链剖分】
BZOJ2243 SDOI2011 染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色 ...
- [BZOJ2243][SDOI2011]染色 解题报告|树链剖分
Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“ ...
- BZOJ2243 [SDOI2011]染色(树链剖分+线段树合并)
题目链接 BZOJ2243 树链剖分 $+$ 线段树 线段树每个节点维护$lc$, $rc$, $s$ $lc$代表该区间的最左端的颜色,$rc$代表该区间的最右端的颜色 $s$代表该区间的所有连续颜 ...
- BZOJ2243: [SDOI2011]染色(树链剖分/LCT)
Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如 ...
- 【BZOJ2243】【SDOI2011】染色(树链剖分,线段树)
题面 我们也要换个花样,这回提供洛谷的题面 题解 线段树+树链剖分大水题 维护颜色段的方法很简单呀... 维护当前区间内的颜色段个数, 以及当前区间左端和右端的颜色, 合并的时候考虑是否要减一下就行了 ...
随机推荐
- 【HNOI】 小A的树 tree-dp
[题目描述]给定一颗树,每个点有各自的权值,任意选取两个点,要求算出这两个点路径上所有点的and,or,xor的期望值. [数据范围]n<=10^5 首先期望可以转化为求树上所有点对的and,o ...
- Spring Boot:定制自己的starter
在学习Spring Boot的过程中,接触最多的就是starter.可以认为starter是一种服务——使得使用某个功能的开发者不需要关注各种依赖库的处理,不需要具体的配置信息,由Spring Boo ...
- Java多线程学习(五)线程间通信知识点补充
系列文章传送门: Java多线程学习(二)synchronized关键字(1) Java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Java多 ...
- linux网络编程之IO函数
Linux操作系统中的IO函数主要有read(),write(),recv(),send(),recvmsg(),sendmsg(),readv(),writev(). 接收数据的recv()函数 # ...
- Ubuntu 14.04 安装gstreamer0.10-ffmpeg
sudo apt-add-repository ppa:mc3man/trusty-media sudo apt-get update sudo apt-get install -y gstreame ...
- Centos7 IP地址配置方法
1.编辑 ifcfg-eth0 文件 # vim /etc/sysconfig/network-scripts/ifcfg-eth0 2.修改如下内容 BOOTPROTO=”static” #dhcp ...
- 利用CSS3伪类做3D按钮
这是通过css3伪类实现的3d按钮,html代码为: <div id="container_buttons"> <p><a class="a ...
- 在k8s 1.7.0上启用dashboard的注意事项
因为自k8s 1.6之后,有基于角色的安全性. 所以很多网上以前的教程就不能使用了. 结合以下三个文档,暂时实现了dashboard界面的推出. http://blog.csdn.net/jinzil ...
- Java学习笔记(十四)——Java静态工厂
[前面的话] 每天过的还行,对我来说,只要让自己充实,生活就会是好的. 学习Java工场方法的原因是最近在使用Spring框架做一个系统,其中有一个注入的方法是使用静态工场方法注入,所以学习一下,基础 ...
- vue之v-text渲染多值
其原理,是利用vue里的computed计算属性来做. 请看代码: <div id='app'> <div v-text="newUsers"></d ...