题目链接

  线段树维护左端颜色,右端颜色,颜色段数量。

  合并的时候看左子树的右端颜色是不是等于右子树的左端颜色,如果等于那么颜色段数量要-1S

  然后在树剖跳链的时候搞同样的操作qwq

  然后就没有然后了

  

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<cstdlib>
#define maxn 500000
#define left (rt<<1)
#define right (rt<<1|1)
#define mid ((l+r)>>1)
#define lson l,mid,left
#define rson mid+1,r,right
using namespace std;
inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} int n,m;
int tag[maxn*];
int deep[maxn];
int dfn[maxn],ID;
int back[maxn];
int q[maxn];
int son[maxn];
int top[maxn];
int father[maxn];
int size[maxn]; struct Edge{
int next,to;
}edge[maxn*];
int head[maxn],num;
inline void add(int from,int to){
edge[++num]=(Edge){head[from],to};
head[from]=num;
} struct Node{
int lcol,rcol,ncol;
Node operator +(const Node a){
Node ans=(Node){lcol,a.rcol,ncol+a.ncol};
if(rcol==a.lcol) ans.ncol--;
return ans;
}
}tree[maxn*]; inline void pushup(int rt){
tree[rt]=tree[left]+tree[right];
} inline void pushdown(int rt){
if(tag[rt]==) return;
tag[left]=tag[right]=tag[rt];
tree[left].lcol=tree[right].lcol=tree[left].rcol=tree[right].rcol=tag[rt];
tree[left].ncol=tree[right].ncol=;
tag[rt]=;
} void build(int l,int r,int rt){
if(l==r){
int last=back[l];
tree[rt]=(Node){q[last],q[last],};
return;
}
build(lson);
build(rson);
pushup(rt);
} void update(int from,int to,int num,int l,int r,int rt){
if(from<=l&&to>=r){
tree[rt]=(Node){num,num,};
tag[rt]=num;
return;
}
pushdown(rt);
if(from<=mid) update(from,to,num,lson);
if(to>mid) update(from,to,num,rson);
pushup(rt);
return;
} int query(int from,int to,int l,int r,int rt){
if(from<=l&&to>=r) return tree[rt].ncol;
pushdown(rt);
int ans=;
if(from<=mid) ans+=query(from,to,lson);
if(to>mid) ans+=query(from,to,rson);
if(from<=mid&&to>mid)
if(tree[left].rcol==tree[right].lcol) ans--;
return ans;
} int qucol(int o,int l,int r,int rt){
if(l==r) return tree[rt].lcol;
pushdown(rt);
if(o<=mid) return qucol(o,lson);
else return qucol(o,rson);
} void findfs(int x,int fa){
deep[x]=deep[fa]+; size[x]=; father[x]=fa;
for(int i=head[x];i;i=edge[i].next){
int to=edge[i].to;
if(to==fa) continue;
findfs(to,x);
size[x]+=size[to];
if(son[x]==||size[son[x]]<size[to]) son[x]=to;
}
} void unidfs(int x,int Top){
top[x]=Top;
dfn[x]=++ID; back[ID]=x;
if(son[x]==) return;
unidfs(son[x],Top);
for(int i=head[x];i;i=edge[i].next){
int to=edge[i].to;
if(to==father[x]||to==son[x]) continue;
unidfs(to,to);
}
} void uplink(int from,int to,int num){
while(top[from]!=top[to]){
if(deep[top[from]]<deep[top[to]]) swap(from,to);
update(dfn[top[from]],dfn[from],num,,n,);
from=father[top[from]];
}
if(deep[from]>deep[to]) swap(from,to);
update(dfn[from],dfn[to],num,,n,);
} int qulink(int from,int to){
int ans=;
while(top[from]!=top[to]){
if(deep[top[from]]<deep[top[to]]) swap(from,to);
ans+=query(dfn[top[from]],dfn[from],,n,);
from=top[from];
if(qucol(dfn[from],,n,)==qucol(dfn[father[from]],,n,)) ans--;
from=father[from];
}
if(deep[from]>deep[to]) swap(from,to);
ans+=query(dfn[from],dfn[to],,n,);
return ans;
} int main(){
n=read(),m=read();
for(int i=;i<=n;++i) q[i]=read();
for(int i=;i<n;++i){
int from=read(),to=read();
add(from,to);
add(to,from);
}
findfs(,);
unidfs(,);
build(,n,);
for(int i=;i<=m;++i){
char ch[]; int a,b;
scanf("%s%d%d",ch,&a,&b);
if(ch[]=='Q') printf("%d\n",qulink(a,b));
else if(ch[]=='C'){
int c=read();
uplink(a,b,c);
}
}
return ;
}

【Luogu】P2486染色(树链剖分)的更多相关文章

  1. [luogu P3384] [模板]树链剖分

    [luogu P3384] [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点 ...

  2. BZOJ 2243 染色 | 树链剖分模板题进阶版

    BZOJ 2243 染色 | 树链剖分模板题进阶版 这道题呢~就是个带区间修改的树链剖分~ 如何区间修改?跟树链剖分的区间询问一个道理,再加上线段树的区间修改就好了. 这道题要注意的是,无论是线段树上 ...

  3. Luogu P2486 [SDOI2011]染色(树链剖分+线段树合并)

    Luogu P2486 [SDOI2011]染色 题面 题目描述 输入输出格式 输入格式: 输出格式: 对于每个询问操作,输出一行答案. 输入输出样例 输入样例: 6 5 2 2 1 2 1 1 1 ...

  4. luogu题解P2486[SDOI2011]染色--树链剖分+trick

    题目链接 https://www.luogu.org/problemnew/show/P2486 分析 看上去又是一道强行把序列上问题搬运到树上的裸题,然而分析之后发现并不然... 首先我们考虑如何在 ...

  5. BZOJ 2243: [SDOI2011]染色 [树链剖分]

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6651  Solved: 2432[Submit][Status ...

  6. bzoj-2243 2243: [SDOI2011]染色(树链剖分)

    题目链接: 2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6267  Solved: 2291 Descript ...

  7. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  8. Bzoj 2243: [SDOI2011]染色 树链剖分,LCT,动态树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 5020  Solved: 1872[Submit][Status ...

  9. [bzoj 2243]: [SDOI2011]染色 [树链剖分][线段树]

    Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“ ...

  10. bzoj2243[SDOI2011]染色 树链剖分+线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 9012  Solved: 3375[Submit][Status ...

随机推荐

  1. Mandelbrot图像

      using System;using System.Collections.Generic;using System.Text; namespace ConsoleApplication3{    ...

  2. [学习笔记] Markdown语法备忘

    Markdown语法总结 标题 # 这是一级标题 ## 这是二级标题 ### 这是三级标题 #### 这是四级标题 ##### 这是五级标题 ###### 这是六级标题 注意#后面要加空格 字体 ** ...

  3. Spring boot 集成Kafka

    搭建Kafka集群,参考: https://www.cnblogs.com/jonban/p/kafka.html 源码示例如下: 1.新建 Maven 项目 kafka 2.pom.xml < ...

  4. WINDOWS-基础:SafeArray的使用方法

    1 SafeArray的作用 使用SafeArray SafeArray是VB中的数组存储方式.通过SafeArray,可以在VC++和VB间相互调用. SafeArray也是Automation中的 ...

  5. idea前后端分离搭建 JavaWeb项目

    我们小组在开发的时候, 承诺了前后端分离, 那么就要求前端和后端需要分开搭建. 不能同时放在一个工程项目中. 大致的思路是开启两个Tomcat, 一个跑前端页面, 一个跑后端程序. 1. idea打开 ...

  6. RuntimeError: cryptography is required for sha256_password or caching_sha2_p

    报错原因:mysql版本身份验证出现问题引起的 我这里报错的地方是在Django里,pycharm连接数据库时出现的 解决办法,安装安装cryptography即可:pip install crypt ...

  7. 转 Spring Security 简介

    https://blog.csdn.net/xlecho/article/details/80026527 Spring Security 简介 2018年04月21日 09:53:02 阅读数:13 ...

  8. Django2.0里urls.py里配置的改变

    从Django2.0开始,urls.py配置方法有很大改变. 1.把url函数换成path 2.不在使用^.$作为路由 3.其他地方以后再进一步研究 下面看一个列子: from django.cont ...

  9. 【php】instanceof

    instanceof 的使用还有一些陷阱必须了解.在 PHP 5.1.0 之前,如果要检查的类名称不存在,instanceof 会调用__autoload().另外,如果该类没有被装载则会产生一个致命 ...

  10. java的重载(overload) (2013-10-11-163 写的日志迁移

    有以下几点: 1.方法名相同. 2.方法的 参数类型.个数.顺序至少有一项不同. 3.方法的返回类型可以不同. 4.方法的修饰符可以不同. 5.仅返回类型和修饰符不同也不可以构成重载.   ----- ...