【BZOJ2243】【SDOI2011】染色(树链剖分,线段树)
题面
题解
线段树+树链剖分大水题
维护颜色段的方法很简单呀。。。
维护当前区间内的颜色段个数,
以及当前区间左端和右端的颜色,
合并的时候考虑是否要减一下就行了
至于跳LCA进行Modify的时候稍微注意一下细节
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAX 110000
#define lson (now<<1)
#define rson (now<<1|1)
using namespace std;
inline int read()
{
register int x=0,t=1;
register char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-'){t=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*t;
}
struct Line
{
int v,next;
}e[MAX<<1];
int h[MAX],cnt=1;
struct Node
{
int c;
int lc,rc;
int ly;
}t[MAX<<2];
inline void Add(int u,int v)
{
e[cnt]=(Line){v,h[u]};
h[u]=cnt++;
}
int n,m,c[MAX],tim;
int dfn[MAX],dep[MAX],line[MAX],ff[MAX],size[MAX],hson[MAX],top[MAX];
void dfs1(int u,int fa)
{
size[u]=1;dep[u]=dep[fa]+1;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;
if(v==fa)continue;
ff[v]=u;
dfs1(v,u);
size[u]+=size[v];
if(size[v]>size[hson[u]])hson[u]=v;
}
}
void dfs2(int u,int tp)
{
top[u]=tp;dfn[u]=++tim;line[tim]=u;
if(hson[u])dfs2(hson[u],tp);
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;
if(v==hson[u]||v==ff[u])continue;
dfs2(v,v);
}
}
void pushup(int now)
{
t[now].c=t[lson].c+t[rson].c;
if(t[lson].rc==t[rson].lc)t[now].c--;
t[now].lc=t[lson].lc;
t[now].rc=t[rson].rc;
}
void pushdown(int now)
{
if(t[now].ly)
{
t[lson].ly=t[rson].ly=t[lson].lc=t[now].ly;
t[rson].lc=t[lson].rc=t[rson].rc=t[now].ly;
t[lson].c=t[rson].c=1;
t[now].ly=0;
}
}
void putlazy(int now,int ly)
{
t[now].c=1;
t[now].lc=t[now].rc=ly;
t[now].ly=ly;
}
void Build(int now,int l,int r)
{
if(l==r)
{
t[now].lc=t[now].rc=c[line[l]];
t[now].c=1;
return;
}
int mid=(l+r)>>1;
Build(lson,l,mid);Build(rson,mid+1,r);
pushup(now);
t[now].lc=t[lson].lc;
t[now].rc=t[rson].rc;
}
int getl(int now,int l,int r,int al)
{
if(al==l)return t[now].lc;
pushdown(now);
int mid=(l+r)>>1;
int re;
if(mid>=al)re=getl(lson,l,mid,al);
else re=getl(rson,mid+1,r,al);
pushup(now);
return re;
}
int getr(int now,int l,int r,int ar)
{
if(r==ar)return t[now].rc;
pushdown(now);
int mid=(l+r)>>1;
int re;
if(mid>=ar)re=getr(lson,l,mid,ar);
else re=getr(rson,mid+1,r,ar);
pushup(now);
return re;
}
int Query(int now,int l,int r,int al,int ar)
{
if(l==al&&r==ar)return t[now].c;
pushdown(now);
int mid=(l+r)>>1;
int re;
if(ar<=mid)re=Query(lson,l,mid,al,ar);
else if(al>mid)re=Query(rson,mid+1,r,al,ar);
else re=(Query(lson,l,mid,al,mid)+Query(rson,mid+1,r,mid+1,ar)-(t[lson].rc==t[rson].lc?1:0));
return re;
}
void Modify(int now,int l,int r,int al,int ar,int cc)
{
if(l==al&&r==ar)
{
putlazy(now,cc);return;
}
int mid=(l+r)>>1;
pushdown(now);
if(ar<=mid)Modify(lson,l,mid,al,ar,cc);
else if(al>mid)Modify(rson,mid+1,r,al,ar,cc);
else
{
Modify(lson,l,mid,al,mid,cc);
Modify(rson,mid+1,r,mid+1,ar,cc);
}
pushup(now);
}
int Answer(int u,int v)
{
int ans=0;
int lu=-1,lv=-1;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])swap(u,v),swap(lu,lv);
int cl=getl(1,1,n,dfn[top[u]]),cr=getr(1,1,n,dfn[u]);
ans+=Query(1,1,n,dfn[top[u]],dfn[u]);
if(cr==lu)ans--;
lu=cl;
u=ff[top[u]];
}
if(dep[u]>dep[v])swap(u,v),swap(lu,lv);
ans+=Query(1,1,n,dfn[u],dfn[v]);
int cl=getl(1,1,n,dfn[u]),cr=getr(1,1,n,dfn[v]);
if(cl==lu)--ans;
if(cr==lv)--ans;
return ans;
}
void Change(int u,int v,int cc)
{
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])swap(u,v);
Modify(1,1,n,dfn[top[u]],dfn[u],cc);
u=ff[top[u]];
}
if(dep[u]>dep[v])swap(u,v);
Modify(1,1,n,dfn[u],dfn[v],cc);
}
int main()
{
n=read();m=read();
for(int i=1;i<=n;++i)c[i]=read();
for(int i=1;i<n;++i)
{
int u=read(),v=read();
Add(u,v);Add(v,u);
}
dfs1(1,0);dfs2(1,1);
Build(1,1,n);
char ch[5];
while(m--)
{
scanf("%s",ch);
if(ch[0]=='C')
{
int a=read(),b=read(),c=read();
Change(a,b,c);
}
else
{
int a=read(),b=read();
printf("%d\n",Answer(a,b));
}
}
return 0;
}
【BZOJ2243】【SDOI2011】染色(树链剖分,线段树)的更多相关文章
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- bzoj2243[SDOI2011]染色 树链剖分+线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 9012 Solved: 3375[Submit][Status ...
- BZOJ2243 [SDOI2011]染色(树链剖分+线段树合并)
题目链接 BZOJ2243 树链剖分 $+$ 线段树 线段树每个节点维护$lc$, $rc$, $s$ $lc$代表该区间的最左端的颜色,$rc$代表该区间的最右端的颜色 $s$代表该区间的所有连续颜 ...
- B20J_2243_[SDOI2011]染色_树链剖分+线段树
B20J_2243_[SDOI2011]染色_树链剖分+线段树 一下午净调这题了,争取晚上多做几道. 题意: 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成 ...
- 2243: [SDOI2011]染色 树链剖分+线段树染色
给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如“112221”由3段组 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- 【bzoj1959】[Ahoi2005]LANE 航线规划 树链剖分+线段树
题目描述 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系——一个巨大的由千百万星球构成的Samuel星系. 星际空间站的Samuel II巨型计算 ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
随机推荐
- centos出现“FirewallD is not running”怎么办
最近在阿里云服务器centos上安装了mysql数据库,默认是不开启远端访问功能,需要设置一下防火墙,在开放默认端口号 3306时提示FirewallD is not running,经过排查发现是防 ...
- 940B Our Tanya is Crying Out Loud
传送门 题目大意 给你n,k,A,B四个数,x=n,有两种操作: 1.将x-1,需支付A个金币 2.将x÷k,需支付B个金币,当且仅当k能整除x时可进行此操作 问将x修改为1至少要花几个金币 分析 模 ...
- Navi.Soft31.产品.微信聊天(永久免费)
1系统简介 1.1功能简述 微信确实是一款优秀的社交的软件,被越来越多的人使用.它的电脑版最新版本是2.6,更新也比较及时,只是它有一个功能差强人意,就是同一台电脑只能运行一个微信号,不知道为何这样设 ...
- Java long类型和Long类型的那些事
还记得最近做了一个项目使用的是Long类型作为主键Id坑死人了,对于我们来说Long类型一样是一个包装类型,类似String类型,使用==符号进行比较的时候有时候会出现问题,建议适应equal()方法 ...
- 安装git,gitlab和TortoiseGit
全部都是默认配置安装 需注册用户:用户名尽量好认 测试用户: 注册成功: 生成密钥: 1.首先使用TortoiseGit自带的Puttygen创建本地的公/私钥对 2.点击Generate按钮,在窗口 ...
- 使用Vue和thrift建立前后端交互的demo
初识thrift thrift 是 facebook 于2007年开发的一款跨平台 RPC(Remote Procedure Call) 软件框架, 它可以在多种平台上进行无缝交互,数据传输使用二进制 ...
- pep 8 规范的一些记录
一.pep8起源 龟叔创立Python的初衷里就有创立一个容易阅读的编程语言,所以亲自操刀写了pep8 代码规范,每个项目开始前都要有一个共识,就是自己的代码规范,pep8 就是一个很好的范本. 二. ...
- java读取文件乱码
List<String> lines=new ArrayList<String>(); BufferedReader br = new BufferedReader(new F ...
- web前端开发工程师工资多少
做web前端开发工程师工资高不高?下面千锋小编为大家分析一下:作为目前互联网行业中的主流技术,Web前端一直是占有重要的地位.尤其是近年来HTML5技术的突飞猛进,使Web前端技术有了更好的发展. ...
- probabilistic robotics_Kalman filter(一)
码农生活告一段落,继续.... 多元正态分布 协方差矩阵,为正定对称矩阵.det表示行列式 协方差反应随机样本变量各分量之间的相关性. 当变量的假设模型不一致时,不适合用高斯滤波. 叠加高斯噪声的线性 ...