【BZOJ 2243】染色
传送门:洛谷 BZOJ
还不会LCT的小伙伴可以看一下这篇博客:LCT总结
我初学动态树时就是看着那篇博客学的,写的很好!
那好 言归正传。
显然树上 x 到 y 的路径的问题都可以用LCT Access一下把路径剖离出来,那主要问题在于如何用Splay 来维护颜色呢?
上图(XP 灵魂画手)
对于Splay树的每一个节点,维护四个信息
c[x] : 节点本身的颜色
cL[x]: 节点对应子树最左端的颜色
cR[x]: 节点对应子树最右端的颜色
tot[x]: 节点对应子树区间的颜色段数
所以upDATA的时候就很显然啦~
1 void pUP(int x){ 2 int lc=ch[x][0],rc=ch[x][1]; 3 4 cL[x]= lc? cL[lc]:c[x]; 5 cR[x]= rc? cR[rc]:c[x]; 6 7 if(lc && rc) tot[x]=tot[lc]+tot[rc]+1-(cR[lc]==c[x])-(cL[rc]==c[x]); 8 9 if(lc &&!rc) tot[x]=tot[lc]+1-(cR[lc]==c[x]); 10 11 if(!lc&& rc) tot[x]=tot[rc]+1-(cL[rc]==c[x]); 12 13 if(!lc&&!rc) tot[x]=1; 14 }
其他部分就和平常的LCT没有什么区别了
哦 对,pushDOWN时要注意 区间翻转,cL和cR要一起翻
全代码~
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<algorithm> 6 7 #define For(i,a,b) for(register int i=a;i<=b;++i) 8 #define Dwn(i,a,b) for(register int i=a;i>=b;--i) 9 #define Pn putchar('\n') 10 #define I inline 11 #define Re register 12 13 using namespace std; 14 15 const int N=1e5+5; 16 17 int ch[N][2],fa[N],c[N],cL[N],cR[N],tot[N],tag[N],st[N],top,tgC[N]; 18 int n,m,x,y,z; 19 char opt; 20 21 I void read(int &v){ 22 v=0; 23 char c=getchar(); 24 while(c<'0'||c>'9')c=getchar(); 25 while(c>='0'&&c<='9')v=v*10+c-'0',c=getchar(); 26 } 27 void write(int x){ 28 if(x>9)write(x/10); 29 int xx=x%10; 30 putchar(xx+'0'); 31 } 32 I bool NOrt(int x){ 33 return ch[fa[x]][1]==x || ch[fa[x]][0]==x; 34 } 35 I void pTAG(int x){ 36 swap(ch[x][0],ch[x][1]); 37 swap(cL[x],cR[x]); 38 tag[x]^=1; 39 } 40 I void pTGC(int x,int Col){ 41 c[x]=cL[x]=cR[x]=Col; 42 tot[x]=1; 43 tgC[x]=Col; 44 } 45 I void pDOWN(int x){ 46 if(tag[x]){ 47 if(ch[x][0])pTAG(ch[x][0]); 48 if(ch[x][1])pTAG(ch[x][1]); 49 tag[x]^=1; 50 } 51 if(tgC[x]){ 52 if(ch[x][0])pTGC(ch[x][0],tgC[x]); 53 if(ch[x][1])pTGC(ch[x][1],tgC[x]); 54 tgC[x]=0; 55 } 56 } 57 I void pUP(int x){ 58 int lc=ch[x][0],rc=ch[x][1]; 59 60 cL[x]= lc? cL[lc]:c[x]; 61 cR[x]= rc? cR[rc]:c[x]; 62 63 if(lc && rc) tot[x]=tot[lc]+tot[rc]+1-(cR[lc]==c[x])-(cL[rc]==c[x]); 64 65 if(lc &&!rc) tot[x]=tot[lc]+1-(cR[lc]==c[x]); 66 67 if(!lc&& rc) tot[x]=tot[rc]+1-(cL[rc]==c[x]); 68 69 if(!lc&&!rc) tot[x]=1; 70 } 71 I bool Wson(int x){ 72 return ch[fa[x]][1]==x; 73 } 74 I void Rotate(int x){ 75 int y=fa[x]; 76 int z=fa[y]; 77 int ws=Wson(x); 78 if(NOrt(y))ch[z][Wson(y)]=x; 79 fa[x]=z; 80 81 ch[y][ws]=ch[x][ws^1]; 82 if(ch[x][ws^1])fa[ch[x][ws^1]]=y; 83 84 ch[x][ws^1]=y; 85 fa[y]=x; 86 87 pUP(y); pUP(x); 88 } 89 I void Splay(int x){ 90 top=0; int now=x; 91 st[++top]=now; 92 while(NOrt(now))st[++top]=now=fa[now]; 93 while(top) pDOWN(st[top--]); 94 95 while(NOrt(x)){ 96 int y=fa[x]; 97 if(NOrt(y)){ 98 if(Wson(y)==Wson(x))Rotate(y); 99 else Rotate(x); 100 } 101 Rotate(x); 102 } 103 } 104 I void Access(int x){ 105 int lst=0; 106 while(x){ 107 Splay(x); ch[x][1]=lst; pUP(x); 108 lst=x; x=fa[x]; 109 } 110 } 111 I void ChangeRt(int x){ 112 Access(x); Splay(x); pTAG(x); 113 } 114 I void Link(int x,int y){ 115 ChangeRt(x); fa[x]=y; 116 } 117 I void Split(int x,int y){ 118 ChangeRt(x); Access(y); Splay(y); 119 } 120 int main(){ 121 read(n); read(m); 122 For(i,1,n){ 123 read(c[i]); tot[i]=1; 124 cL[i]=cR[i]=c[i]; 125 }; 126 For(i,1,n-1){ 127 read(x); read(y); 128 Link(x,y); 129 } 130 For(i,1,m){ 131 opt=getchar(); 132 while(opt!='C'&&opt!='Q')opt=getchar(); 133 if(opt=='C'){ 134 read(x); read(y); read(z); 135 Split(x,y); pTGC(y,z); 136 } 137 if(opt=='Q'){ 138 read(x); read(y); 139 Split(x,y); 140 write(tot[y]); Pn; 141 } 142 } 143 return 0; 144 }
转载于:https://www.cnblogs.com/HLAUV/p/10330934.html
【BZOJ 2243】染色相关推荐
- BZOJ 2243 染色(树链剖分好题)
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 7971 Solved: 2990 [Submit][Stat ...
- [BZOJ 2243] 染色
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=2243 分析 树链剖分练习题 比较难的地方在于两端相邻区间交界处的颜色有可能相同. 那么此时查询 ...
- HYSBZ - 2243染色——树链剖分+线段树建树技巧
[题目描述] HYSBZ - 2243染色 [题目分析] 我一直没有看清楚题,以为求的是路径上出现颜色的种类,然后就写了一个区间染色的线段树进行维护,过样例的时候才发现题读错了,人家要求的是路径上出现 ...
- BZOJ 2243: [SDOI2011]染色
2243: [SDOI2011]染色 >原题链接< Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点 ...
- BZOJ 2243 树链剖分
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2243 题意:中文题目 思路:树链剖分.首先考虑求区间颜色段数的问题, 我们可以用线段树维护 ...
- bzoj 刷题计划~_~
bzoj 2818 两个互质的数的gcd=1,所以他们同时乘一个素数那么他们的gcd=这个素数,所以枚举素数p找n/p以内有多少对互质数,用欧拉函数. bzoj 2809 可并堆,对于每一个子树显然是 ...
- linux脚本ipddr.sh 是什么,MTK DDR调试
1. 获取 flash id: 硬件信息:通过这个节点可以知道当前flash的id,上层根据id找到对应的flash名字. cat /sys/block/mmcblk0/device/cid \ker ...
- BZOJ 2303 方格染色(带权并查集)
要使得每个2*2的矩形有奇数个红色,如果我们把红色记为1,蓝色记为0,那么我们得到了这2*2的矩形里的数字异或和为1. 对于每个方格则有a(i,j)^a(i-1,j)^a(i,j-1)^a(i-1,j ...
- bzoj 4033: [HAOI2015]树上染色(树形DP)
4033: [HAOI2015]树上染色 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 1786 Solved: 754 [Submit][Sta ...
最新文章
- 《Java从入门到放弃》框架入门篇:hibernate基本用法
- Scaleform GFx
- flex 平铺布局_flex布局及各种布局的总结
- 最近打算再写一个 局域网聊天软件
- Ext3 -- Form 实例。 用来migrate file 数据到DB用的
- 6. PHP bcompiler
- 转:IV值和WOE值的理解
- K8s中nodePort、port、targetPort、hostPort介绍
- Android反编译工具绿色版V2.0(改进版)
- python手势识别算法_Hand-gesture-recognition 这是一个用python写的手势识别的算法 - 下载 - 搜珍网...
- centos6安装wget
- C#引用interop.taskscheduler.dll
- 音视频入门之如何绘制一张图片
- php图片素描化,html5利用canvas实现图片转素描效果
- welcome.php,welcome.php
- 机器学习基础——生成模型和判别模型
- 自动紧急制动(AEB)
- String类②——StringBuilder和StringBuffer
- 【思科模拟器实验】多端口路由器互连VLAN实验
- 小猪CMS多用户微信营销平台短信插件开发