【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 为根的子 ...
随机推荐
- ConcurrenHashMap源码分析(二)
本篇博客的目录: 一:put方法源码 二:get方法源码 三:rehash的过程 四:总结 一:put方法的源码 首先,我们来看一下segment内部类中put方法的源码,这个方法它是segment片 ...
- href与src 区别
src 是可替换的文本支撑,将指向的内容引入文档当前标签所在的位置, 当浏览器解析到该标签时,将暂停其它资源的下载处理, 请求该标签的src ,下载指向的外部资源并应用到当前文档, 所以js 脚本一般 ...
- [记录]一则清理MySQL大表以释放磁盘空间的案例
一则清理MySQL大表以释放磁盘空间的案例 一.基本情况: 1.dbtest库554G,先清理st_online_time_away_ds(37G)表的数据,保留半年的数据: 1)删除的数据:sele ...
- bzoj 2176 最小表示
2176: Strange string Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 419 Solved: 174[Submit][Status ...
- WEB 小案例 -- 网上书城(二)
寒假结束了,自己的颓废时间同样结束了,早该继续写博客了,尽管我的格式以及内容由于各种原因老被卡,但必须坚持写下去!!! 上次我们对于本案例的数据库部分进行了阐述,这次主要接着上次的内容分享本案例的翻页 ...
- java日期转化
package com.kang.util; import java.text.ParseException; import java.text.SimpleDateFormat; import ja ...
- gitlab启用https
为了防止内网渗透,将gitlab服务的访问添加了ssl,具体步骤如下: 修改配置文件 [xieshuang@VM_177_101_centos gitlab]$ sudo vim /etc/gitla ...
- swift 之归档和解归档
swift 之归档和解归档 数据持久化的方式有很多种,归档是其中的一种,说起数据持久化的方式,iOS 中基本有以下几种方式:sqlite存储.coredata存储.UserDefault存储.归档.p ...
- 写出一条Sql语句:取出表Customer中第31到第40记录(SQLServer,以自动增长的Id作为主键,注意:Id可能不是连续的。
select top 10 * from (select ROW_NUMBER() over(order by Id) as rows,* from Customer) as C where C.ro ...
- java I/O框架 (三)基本流
概述 基本流有字节输入输出流(InputStream,OutputStream),和字符输入输出流(Reader,Writer),它们都是抽象类,作为Java IO API中其他所有流的父类存在. 我 ...