#树链剖分,线段树#洛谷 2486 [SDOI2011]染色
分析
就是把维护颜色段和树结合起来,
注意拼接的时候要减去中间相同的部分
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int N=100011; struct node{int y,next;}e[N<<1];
int dep[N],as[N],fat[N],top[N],dfn[N],tot,son[N],n,Lc,Rc,lL,rR,m;
int col[N],nfd[N],big[N],w[N<<2],lazy[N<<2],lc[N<<2],rc[N<<2],k=1;
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
inline void add(int x,int y){
e[++k]=(node){y,as[x]},as[x]=k,
e[++k]=(node){x,as[y]},as[y]=k;
}
inline void pup(int k){
lc[k]=lc[k<<1],rc[k]=rc[k<<1|1];
w[k]=w[k<<1]+w[k<<1|1]-(rc[k<<1]==lc[k<<1|1]);
}
inline void pdown(int k){
lc[k<<1]=lc[k<<1|1]=lc[k],lazy[k<<1]=lazy[k<<1|1]=1,
rc[k<<1]=rc[k<<1|1]=rc[k],w[k<<1]=w[k<<1|1]=1,lazy[k]=0;
}
inline void build(int k,int l,int r){
if (l==r){
lc[k]=rc[k]=col[nfd[l]],w[k]=1;
return;
}
rr int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
pup(k);
}
inline void update(int k,int l,int r,int x,int y,int z){
if (l==x&&r==y){
lc[k]=rc[k]=z,w[k]=lazy[k]=1;
return;
}
if (lazy[k]) pdown(k);
rr int mid=(l+r)>>1;
if (y<=mid) update(k<<1,l,mid,x,y,z);
else if (x>mid) update(k<<1|1,mid+1,r,x,y,z);
else update(k<<1,l,mid,x,mid,z),
update(k<<1|1,mid+1,r,mid+1,y,z);
pup(k);
}
inline signed query(int k,int l,int r,int x,int y){
if (l==x&&r==y){
if (l==lL) Lc=lc[k];
if (r==rR) Rc=rc[k];
return w[k];
}
if (lazy[k]) pdown(k);
rr int mid=(l+r)>>1;
if (y<=mid) return query(k<<1,l,mid,x,y);
else if (x>mid) return query(k<<1|1,mid+1,r,x,y);
else {
rr int ansL=query(k<<1,l,mid,x,mid),
ansR=query(k<<1|1,mid+1,r,mid+1,y);
return ansL+ansR-(rc[k<<1]==lc[k<<1|1]);
}
}
inline void dfs1(int x,int fa){
dep[x]=dep[fa]+1,fat[x]=fa,son[x]=1;
for (rr int i=as[x],mson=-1;i;i=e[i].next)
if (e[i].y!=fa){
dfs1(e[i].y,x);
son[x]+=son[e[i].y];
if (son[e[i].y]>mson) big[x]=e[i].y,mson=son[e[i].y];
}
}
inline void dfs2(int x,int linp){
dfn[x]=++tot,nfd[tot]=x,top[x]=linp;
if (!big[x]) return; dfs2(big[x],linp);
for (rr int i=as[x];i;i=e[i].next)
if (e[i].y!=fat[x]&&e[i].y!=big[x]) dfs2(e[i].y,e[i].y);
}
inline void Update(int x,int y,int z){
for (;top[x]!=top[y];x=fat[top[x]]){
if (dep[top[x]]<dep[top[y]]) x^=y,y^=x,x^=y;
update(1,1,n,dfn[top[x]],dfn[x],z);
}
if (dep[x]>dep[y]) x^=y,y^=x,x^=y;
update(1,1,n,dfn[x],dfn[y],z);
}
inline signed Query(int x,int y){
int ans=0,xLc=-1,yLc=-1;
for (;top[x]!=top[y];x=fat[top[x]]){
if (dep[top[x]]<dep[top[y]]){
x^=y,y^=x,x^=y;
if (xLc^yLc) xLc^=yLc,yLc^=xLc,xLc^=yLc;
}
lL=dfn[top[x]],rR=dfn[x];
ans+=query(1,1,n,dfn[top[x]],dfn[x]);
ans-=(Rc==xLc),xLc=Lc;
}
if (dep[x]<dep[y]){
x^=y,y^=x,x^=y;
if (xLc^yLc) xLc^=yLc,yLc^=xLc,xLc^=yLc;
}
lL=dfn[y],rR=dfn[x];
ans+=query(1,1,n,dfn[y],dfn[x]);
ans-=(Rc==xLc)+(Lc==yLc);//除了x的拼接还有y的拼接
return ans;
}
signed main(){
n=iut(); m=iut();
for (rr int i=1;i<=n;++i) col[i]=iut();
for (rr int i=1;i<n;++i) add(iut(),iut());
dfs1(1,0),dfs2(1,1),build(1,1,n);
for (;m;--m){
rr char c=getchar();
while (c!='C'&&c!='Q') c=getchar();
rr int x=iut(),y=iut();
if (c=='C') Update(x,y,iut());
else print(Query(x,y)),putchar(10);
}
return 0;
}
#树链剖分,线段树#洛谷 2486 [SDOI2011]染色的更多相关文章
- 洛谷P4092 [HEOI2016/TJOI2016]树 并查集/树链剖分+线段树
正解:并查集/树链剖分+线段树 解题报告: 传送门 感觉并查集的那个方法挺妙的,,,刚好又要复习下树剖了,所以就写个题解好了QwQ 首先说下并查集的方法趴QwQ 首先离线,读入所有操作,然后dfs遍历 ...
- 洛谷P3313 [SDOI2014]旅行 题解 树链剖分+线段树动态开点
题目链接:https://www.luogu.org/problem/P3313 这道题目就是树链剖分+线段树动态开点. 然后做这道题目之前我们先来看一道不考虑树链剖分之后完全相同的线段树动态开点的题 ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
- HDU4897 (树链剖分+线段树)
Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...
- Aizu 2450 Do use segment tree 树链剖分+线段树
Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...
- 【POJ3237】Tree(树链剖分+线段树)
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
随机推荐
- socket及黏包现象及解决黏包---day28
1.四次挥手(补充) 客户端向服务端发送一个请求消息,断开连接(代表客户端没有数据传输了) 服务端接收请求,发出响应 等到服务端所有数据收发完毕之后 服务端向客户端发送断开连接的请求 客户端接收请求后 ...
- 【LeetCode哈希表#4】梦开始的地方:两数之和(map),以及关于容器map的一些代码技巧
两数之和 力扣题目链接(opens new window) 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种 ...
- [Rust] Workspace,Package, Crate 和 Module
package(包) 一个 package 对应一个项目,package 的信息在 Cargo.toml 里面定义. crate(木箱.箱子) crate 指的是 package 编译后的输出文件.以 ...
- NodeJS开启GZIP功能
gzip是用于压缩,效果特别好,js.css等文件的压缩率一般高达70% 具体方法如下: 先安装一个依赖 npm install compression --save 然后在已有代码里(一般是app. ...
- 【Azure 环境】使用az login登录遇见OSError: [WinError -2146893813] : '' 错误
问题描述 使用 az login指令登录,遇见 OS Error: [WinError -2146893813] : '', 在指令中添加 --debug后,输出的错误消息为: urllib3.con ...
- 【Azure 环境】Azure门户中 Metrics 图表的聚合指标每项具体代表什么意思呢?
问题描述 下图中,指标里的每项聚合指标具体代表什么呢? 问题解答 Azure Metrics 指标中提供了五种基本的聚合类型. Sum - 在聚合间隔内捕获的所有值的总和. 有时称为总聚合. Coun ...
- Huggingface初上手即ERNIE-gram句子相似性实战
大模型如火如荼的今天,不学点语言模型(LM)相关的技术实在是说不过去了.只不过由于过往项目用到LM较少,所以学习也主要停留在直面--动眼不动手的水平.Huggingface(HF)也是现在搞LM离不开 ...
- 浅析图数据库 Nebula Graph 数据导入工具——Spark Writer
从 Hadoop 说起 近年来随着大数据的兴起,分布式计算引擎层出不穷.Hadoop 是 Apache 开源组织的一个分布式计算开源框架,在很多大型网站上都已经得到了应用.Hadoop 的设计核心思想 ...
- SSRF概述
SSRF(service side request forgery) 1.攻击的目标: 从外网无法访问的内部系统 2.形成的原因: 大部分是由服务器端提供了从其他服务器应用获取数据的功能.且没有对目标 ...
- sqlserver 查看执行计划
-- 清除执行计划缓存 DBCC FREEPROCCACHE -- 查看缓存执行计划 SELECT * FROM sys.dm_exec_cached_plans as p CROSS APPLY s ...