传送门:洛谷   BZOJ

还不会LCT的小伙伴可以看一下这篇博客:LCT总结

我初学动态树时就是看着那篇博客学的,写的很好!

那好 言归正传。

显然树上 x 到 y 的路径的问题都可以用LCT Access一下把路径剖离出来,那主要问题在于如何用Splay 来维护颜色呢?

上图(XP 灵魂画手)

对于Splay树的每一个节点,维护四个信息

c[x] : 节点本身的颜色

cL[x]: 节点对应子树最左端的颜色

cR[x]: 节点对应子树最右端的颜色

tot[x]: 节点对应子树区间的颜色段数

所以upDATA的时候就很显然啦~

 void pUP(int x){
int lc=ch[x][],rc=ch[x][]; cL[x]= lc? cL[lc]:c[x];
cR[x]= rc? cR[rc]:c[x]; if(lc && rc) tot[x]=tot[lc]+tot[rc]+-(cR[lc]==c[x])-(cL[rc]==c[x]); if(lc &&!rc) tot[x]=tot[lc]+-(cR[lc]==c[x]); if(!lc&& rc) tot[x]=tot[rc]+-(cL[rc]==c[x]); if(!lc&&!rc) tot[x]=;
}

其他部分就和平常的LCT没有什么区别了

哦 对,pushDOWN时要注意 区间翻转,cL和cR要一起翻

全代码~

 #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm> #define For(i,a,b) for(register int i=a;i<=b;++i)
#define Dwn(i,a,b) for(register int i=a;i>=b;--i)
#define Pn putchar('\n')
#define I inline
#define Re register using namespace std; const int N=1e5+; int ch[N][],fa[N],c[N],cL[N],cR[N],tot[N],tag[N],st[N],top,tgC[N];
int n,m,x,y,z;
char opt; I void read(int &v){
v=;
char c=getchar();
while(c<''||c>'')c=getchar();
while(c>=''&&c<='')v=v*+c-'',c=getchar();
}
void write(int x){
if(x>)write(x/);
int xx=x%;
putchar(xx+'');
}
I bool NOrt(int x){
return ch[fa[x]][]==x || ch[fa[x]][]==x;
}
I void pTAG(int x){
swap(ch[x][],ch[x][]);
swap(cL[x],cR[x]);
tag[x]^=;
}
I void pTGC(int x,int Col){
c[x]=cL[x]=cR[x]=Col;
tot[x]=;
tgC[x]=Col;
}
I void pDOWN(int x){
if(tag[x]){
if(ch[x][])pTAG(ch[x][]);
if(ch[x][])pTAG(ch[x][]);
tag[x]^=;
}
if(tgC[x]){
if(ch[x][])pTGC(ch[x][],tgC[x]);
if(ch[x][])pTGC(ch[x][],tgC[x]);
tgC[x]=;
}
}
I void pUP(int x){
int lc=ch[x][],rc=ch[x][]; cL[x]= lc? cL[lc]:c[x];
cR[x]= rc? cR[rc]:c[x]; if(lc && rc) tot[x]=tot[lc]+tot[rc]+-(cR[lc]==c[x])-(cL[rc]==c[x]); if(lc &&!rc) tot[x]=tot[lc]+-(cR[lc]==c[x]); if(!lc&& rc) tot[x]=tot[rc]+-(cL[rc]==c[x]); if(!lc&&!rc) tot[x]=;
}
I bool Wson(int x){
return ch[fa[x]][]==x;
}
I void Rotate(int x){
int y=fa[x];
int z=fa[y];
int ws=Wson(x);
if(NOrt(y))ch[z][Wson(y)]=x;
fa[x]=z; ch[y][ws]=ch[x][ws^];
if(ch[x][ws^])fa[ch[x][ws^]]=y; ch[x][ws^]=y;
fa[y]=x; pUP(y); pUP(x);
}
I void Splay(int x){
top=; int now=x;
st[++top]=now;
while(NOrt(now))st[++top]=now=fa[now];
while(top) pDOWN(st[top--]); while(NOrt(x)){
int y=fa[x];
if(NOrt(y)){
if(Wson(y)==Wson(x))Rotate(y);
else Rotate(x);
}
Rotate(x);
}
}
I void Access(int x){
int lst=;
while(x){
Splay(x); ch[x][]=lst; pUP(x);
lst=x; x=fa[x];
}
}
I void ChangeRt(int x){
Access(x); Splay(x); pTAG(x);
}
I void Link(int x,int y){
ChangeRt(x); fa[x]=y;
}
I void Split(int x,int y){
ChangeRt(x); Access(y); Splay(y);
}
int main(){
read(n); read(m);
For(i,,n){
read(c[i]); tot[i]=;
cL[i]=cR[i]=c[i];
};
For(i,,n-){
read(x); read(y);
Link(x,y);
}
For(i,,m){
opt=getchar();
while(opt!='C'&&opt!='Q')opt=getchar();
if(opt=='C'){
read(x); read(y); read(z);
Split(x,y); pTGC(y,z);
}
if(opt=='Q'){
read(x); read(y);
Split(x,y);
write(tot[y]); Pn;
}
}
return ;
}

【BZOJ 2243】染色的更多相关文章

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

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

  2. BZOJ 2243 染色(树链剖分好题)

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 7971  Solved: 2990 [Submit][Stat ...

  3. BZOJ 2243 染色 (线段树+树链剖分)

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

  4. BZOJ 2243 染色

    树链剖分+区间染色 因为是一颗树不是森林,所以应该用树剖就行,但是LCT好像也能写.. 直接用线段树维护树上的节点,注意pushdown还有询问的时候要考虑区间相交的地方,也就是左孩子右边和有孩子的左 ...

  5. BZOJ - 2243 染色 (树链剖分+线段树+区间合并)

    题目链接 线段树维护区间连续段个数即可.设lc为区间左端点颜色,rc为区间右端点颜色,则合并两区间的时候,如果左区间右端点和右区间左端点颜色相同,则连续段个数-1. 在树链上的区间合并可以定义一个结构 ...

  6. BZOJ 2243 染色 树链剖分

    题意: 给出一棵树,每个顶点上有个颜色\(c_i\). 有两种操作: C a b c 将\(a \to b\)的路径所有顶点上的颜色变为c Q a b 查询\(a \to b\)的路径上的颜色段数,连 ...

  7. BZOJ - 2243 染色 (LCT链修改+链查询)

    同样是可以用LCT解决的树剖问题之一. 注意反转的时候要考虑对左右端点颜色的影响,而且要先反转再打标记(这点不知道为啥) #include<bits/stdc++.h> using nam ...

  8. [BZOJ 2243] [SDOI 2011] 染色 【树链剖分】

    题目链接:BZOJ - 2243 题目分析 树链剖分...写了200+行...Debug了整整一天+... 静态读代码读了 5 遍 ,没发现错误,自己做小数据也过了. 提交之后全 WA . ————— ...

  9. hysbz 2243 染色(树链剖分)

    题目链接:hysbz 2243 染色 题目大意:略. 解题思路:树链剖分+线段树的区间合并,可是区间合并比較简单,节点仅仅要记录左右端点的颜色就可以. #include <cstdio> ...

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

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

随机推荐

  1. 加州小学grade1,学习计划

    Visual vocabulary Grammar Spelling Maths Chapter 1 Patterns and Number SenseChapter 2Understanding A ...

  2. 部署asp.net网站的小问题

    C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG   web.config  修改 trust level="Full"

  3. codeforces 706C C. Hard problem(dp)

    题目链接: C. Hard problem time limit per test 1 second memory limit per test 256 megabytes input standar ...

  4. codeforces 558A A. Lala Land and Apple Trees(水题)

    题目链接: A. Lala Land and Apple Trees time limit per test 1 second memory limit per test 256 megabytes ...

  5. FAQrobot 聊天机器人笔记

    follow: https://github.com/ofooo/FAQrobot  这是一个简单的基于问词匹配的自动问答,获取与用户问句Q1最匹配的知识库中的问句Q2,Q2的答案就是Q1的答案. 首 ...

  6. NO1:安装VMLinux虚拟机,安装配置Samba实现Linux与Windows文件共享

    离开技术好些年,仅凭记忆开始学习.同时决定在Linux系统学习C语言. 一.下午安装了VM 8.0,安装RedHat Enterpris Server 6.4虚拟操作系统,都还比较顺利. 二.要实现L ...

  7. bzoj 2865 字符串识别 —— 后缀数组

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2865 唯一出现的子串就是每个后缀除去和别的后缀最长的 LCP 之外的前缀: 所以用这个更新一 ...

  8. TCP点对点穿透探索--失败

    TCP点对点穿透探索 点对点穿透是穿透什么 点对点穿透,需要实现的是对NAT的穿透.想实现NAT的穿透,当然要先了解NAT到底是什么,以及NAT是用来干什么的.NAT全称Network Address ...

  9. 资源:template

    ylbtech-资源: 1.返回顶部   2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部     6.返回顶部   作者:ylbtech出处:http://ylbtech.cnbl ...

  10. Component概念

    转自:http://www.cnblogs.com/NEOCSL/archive/2012/05/06/2485227.html 1.总结 Component就是组建的意思,可以在DefaultPro ...