BZOJ2243[SDOI2011]染色——树链剖分+线段树
题目描述
输入
输出
对于每个询问操作,输出一行答案。
样例输入
2 2 1 2 1 1
1 2
1 3
2 4
2 5
2 6
Q 3 5
C 2 1 1
Q 3 5
C 5 1 2
Q 3 5
样例输出
1
2
提示
数N<=10^5,操作数M<=10^5,所有的颜色C为整数且在[0, 10^9]之间。
一道很有思维含量且细节挺多的题。首先想如何求序列上一个区间有几个颜色段?线段树每个点维护这个点所代表区间的左右端点颜色及这个区间的颜色段数就好了。在树上操作就直接dfs出树剖序然后架在线段树上。但要注意一点,每次查询时两点在跳lca的过程中每次跳的是一条重链,两条重链的相接的两个点颜色如果相同就要把答案数减1,所以还要维护每次跳的链头的颜色。当最后两个点跳到同一个重链上时这两点间的链的两头要分别判断一下。
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m;
int tot;
int num;
int x,y,z;
char ch[2];
int s[100010];
int d[100010];
int a[800010];
int f[100010];
int v[100010];
int q[100010];
int ls[800010];
int rs[800010];
int to[200010];
int sum[800010];
int son[100010];
int top[100010];
int size[100010];
int head[100010];
int next[200010];
void add(int x,int y)
{
tot++;
next[tot]=head[x];
head[x]=tot;
to[tot]=y;
}
void dfs(int x,int fa)
{
size[x]=1;
f[x]=fa;
d[x]=d[fa]+1;
for(int i=head[x];i;i=next[i])
{
if(to[i]!=fa)
{
dfs(to[i],x);
size[x]+=size[to[i]];
if(size[to[i]]>size[son[x]])
{
son[x]=to[i];
}
}
}
}
void dfs2(int x,int tp)
{
s[x]=++num;
q[num]=x;
top[x]=tp;
if(son[x])
{
dfs2(son[x],tp);
}
for(int i=head[x];i;i=next[i])
{
if(to[i]!=f[x]&&to[i]!=son[x])
{
dfs2(to[i],to[i]);
}
}
}
void pushup(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
if(rs[rt<<1]==ls[rt<<1|1])
{
sum[rt]--;
}
ls[rt]=ls[rt<<1];
rs[rt]=rs[rt<<1|1];
}
void pushdown(int rt)
{
if(a[rt]!=-1)
{
a[rt<<1]=a[rt];
a[rt<<1|1]=a[rt];
ls[rt<<1]=a[rt];
rs[rt<<1]=a[rt];
ls[rt<<1|1]=a[rt];
rs[rt<<1|1]=a[rt];
sum[rt<<1]=1;
sum[rt<<1|1]=1;
a[rt]=-1;
}
}
void build(int rt,int l,int r)
{
a[rt]=-1;
if(l==r)
{
ls[rt]=rs[rt]=v[q[l]];
sum[rt]=1;
return ;
}
int mid=(l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
pushup(rt);
}
void change(int rt,int l,int r,int L,int R,int v)
{
if(L<=l&&r<=R)
{
sum[rt]=1;
ls[rt]=v;
rs[rt]=v;
a[rt]=v;
return ;
}
pushdown(rt);
int mid=(l+r)>>1;
if(L<=mid)
{
change(rt<<1,l,mid,L,R,v);
}
if(R>mid)
{
change(rt<<1|1,mid+1,r,L,R,v);
}
pushup(rt);
}
int query(int rt,int l,int r,int L,int R)
{
if(L<=l&&r<=R)
{
return sum[rt];
}
pushdown(rt);
int mid=(l+r)>>1;
if(R<=mid)
{
return query(rt<<1,l,mid,L,R);
}
else if(L>mid)
{
return query(rt<<1|1,mid+1,r,L,R);
}
if(rs[rt<<1]==ls[rt<<1|1])
{
return query(rt<<1,l,mid,L,R)+query(rt<<1|1,mid+1,r,L,R)-1;
}
else
{
return query(rt<<1,l,mid,L,R)+query(rt<<1|1,mid+1,r,L,R);
}
}
int find(int rt,int l,int r,int k)
{
if(l==r)
{
return ls[rt];
}
pushdown(rt);
int mid=(l+r)>>1;
if(k<=mid)
{
return find(rt<<1,l,mid,k);
}
else
{
return find(rt<<1|1,mid+1,r,k);
}
}
void color(int x,int y,int v)
{
while(top[x]!=top[y])
{
if(d[top[x]]<d[top[y]])
{
swap(x,y);
}
change(1,1,n,s[top[x]],s[x],v);
x=f[top[x]];
}
if(d[x]>d[y])
{
swap(x,y);
}
change(1,1,n,s[x],s[y],v);
}
int ask(int x,int y)
{
int t1=-1;
int s1=-1;
int res=0;
while(top[x]!=top[y])
{
if(d[top[x]]>d[top[y]])
{
res+=query(1,1,n,s[top[x]],s[x]);
if(s1==find(1,1,n,s[x]))
{
res--;
}
s1=find(1,1,n,s[top[x]]);
x=f[top[x]];
}
else
{
res+=query(1,1,n,s[top[y]],s[y]);
if(t1==find(1,1,n,s[y]))
{
res--;
}
t1=find(1,1,n,s[top[y]]);
y=f[top[y]];
}
}
if(x==y)
{
res++;
int miku=find(1,1,n,s[x]);
if(miku==t1)
{
res--;
}
if(miku==s1)
{
res--;
}
}
else
{
if(d[x]>d[y])
{
res+=query(1,1,n,s[y],s[x]);
}
else
{
res+=query(1,1,n,s[x],s[y]);
}
if(find(1,1,n,s[x])==s1)
{
res--;
}
if(find(1,1,n,s[y])==t1)
{
res--;
}
}
return res;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&v[i]);
}
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dfs(1,0);
dfs2(1,1);
build(1,1,n);
for(int i=1;i<=m;i++)
{
scanf("%s",ch);
if(ch[0]=='C')
{
scanf("%d%d%d",&x,&y,&z);
color(x,y,z);
}
else
{
scanf("%d%d",&x,&y);
printf("%d\n",ask(x,y));
}
}
}
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 为根的子 ...
随机推荐
- pycharm安装mysql驱动包
新的环境配置pycharm的项目时,发现pycharm不能连接到mysql数据库.由于安了java环境但是还没配置相关的库,并且jetbrains家的IDE一般都是java写的,于是猜想可能是java ...
- 天财商龙SQL查询ID登陆POS情况
SELECT * FROM [tcgem_client0001].[dbo].[TCB_POS] ' --查询ID登陆POS情况
- office web apps搭建与解决方案
微软office在线预览解决方案https://view.officeapps.live.com/op/view.aspx?src=http://storage.xuetangx.com/public ...
- springboot调用http方式
1.httpclient 2.okhttp 3.feign 安装Gradle包 compile 'org.springframework.cloud:spring-cloud-starter-open ...
- Multi label 多标签分类问题(Pytorch,TensorFlow,Caffe)
适用场景:一个输入对应多个label,或输入类别间不互斥 调用函数: 1. Pytorch使用torch.nn.BCEloss 2. Tensorflow使用tf.losses.sigmoid_cro ...
- [转]Prometheus 与 Grafana 实现服务器运行状态监控
http://flintx.me/2017/12/12/Prometheus%20+%20Grafana%20%E5%AE%9E%E7%8E%B0%E6%9C%8D%E5%8A%A1%E5%99%A8 ...
- 在 Xshell 中 使用 hbase shell 进入后 无法删除 问题
在 Xshell 中 使用 hbase shell 进入后 无法删除 问题: 在hbase shell下,误输入的指令不能使用backspace和delete删除,使用过的人都知道,这是有多坑,有多苦 ...
- TypeScript学习笔记 (一)基础特性
一. 字符串新特性 1. 多行字符串 var str = ``; 2. 字符串模板 var world = "world"; var str = `hello ${world}`; ...
- net core体系-web应用程序-4net core2.0大白话带你入门-7asp.net core日志组件(Logger和Nlog)
asp.net core日志组件 日志介绍 Logging的使用 1. appsettings.json中Logging的介绍 Logging的配置信息是保存在appsettings.json配置 ...
- Idea问题:“marketplace plugins are not loaded”解决方案
博主本人遇见该问题时是想要通过Idea的plugins工具下载阿里巴巴的代码规约工具 但是在我点开settings,然后打开plugins工具时竟然给我提示“marketplace plugins a ...