【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 为根的子 ...
随机推荐
- WebSocket就是这么简单
前言 今天在慕课网上看到了Java的新教程(Netty入门之WebSocket初体验):https://www.imooc.com/learn/941 WebSocket我是听得很多,没有真正使用过的 ...
- php分布式redis实现session共享
方法一:找到配置文件php.ini,修改为下面内容,保存并重启服务 session.save_handler = redis session.save_path = "tcp://127.0 ...
- SQL查询练习一(From LeetCode)
请选用MySQL进行测试. 1.找出后一天比前一天温度高的日期(E) 思路:将该表进行自关联,然后选择出日期靠后的一天,最后选择温度高的日期 select Weather.Id from Weath ...
- 加入GIMPS项目,寻找梅森素数!
截止到目前为止人类共找到了50个梅森素数,其中最后16个梅森素数都是通过GIMPS项目找到的. 为了激励人们寻找梅森素数和促进网格技术发展,总部设在美国旧金山的电子前沿基金会(EFF)于1999年3月 ...
- LIMS系统仪器数据采集-使用xpdf解析pdf内容
不同语言解析PDF内容都有各自的库,比如Java的pdfbox,.net的itextsharp. c#解析PDF文本,关键代码可参考: http://www.cnblogs.com/mahongbia ...
- 54.1 怎样才算学会django? 知道这28个知识点才算会django2
学到什么程度才算会django了?这篇文章帮你梳理一下 关于django2的28个不可不知的知识点总结: 1.cookie操作: -客户端本地存储的键值对 2.session操作: -服务器端可以保存 ...
- dubbox系列【一】——dubbox简介
1.dubbox是什么? dubbox是当当网开源的开源分布式服务框架,基于阿里巴巴dubbo. 1个框架 + 2个方案:分布式服务框架 + RPC远程调用方案 + SOA服务治理方案. 2.dubb ...
- 洛谷P3381 - 【模板】最小费用最大流
原题链接 题意简述 模板题啦~ 题解 每次都以费用作为边权求一下最短路,然后沿着最短路增广. Code //[模板]最小费用最大流 #include <cstdio> #include & ...
- 高并发场景下的httpClient优化使用
1.背景 我们有个业务,会调用其他部门提供的一个基于http的服务,日调用量在千万级别.使用了httpclient来完成业务.之前因为qps上不去,就看了一下业务代码,并做了一些优化,记录在这里. 先 ...
- Enable multi-tenancy on ironic
Multi-tenancy 是openstack ironic从Ocata版本开始支持的新特性,通过network-generic-switch插件控制交换机,Ironic可以实现在不同租户间机网络隔 ...