bzoj2243-染色(动态树lct)
解析:增加三个变量lc(最左边的颜色),rc(最右边的颜色),sum(连续相同颜色区间段数)。然后就是区间合并的搞法。我就不详细解释了,估计你已经想到
如何做了。
代码
- #include<cstdio>
- #include<cstring>
- #include<string>
- #include<vector>
- #include<algorithm>
- using namespace std;
- const int maxn=;
- int N,M,C[maxn];
- struct lct
- {
- lct *fa,*son[];
- int rev,c,setc,lc,rc,sum;
- };
- struct LCT
- {
- lct data[maxn];
- lct *null;
- void init(int Size=maxn-) //初始化
- {
- null=data; //null指向首元素
- for(int i=;i<=Size;i++)
- {
- data[i].son[]=data[i].son[]=data[i].fa=null;
- data[i].rev=;
- data[i].c=data[i].lc=data[i].rc=C[i];
- data[i].setc=-;
- data[i].sum=;
- }
- null->c=null->lc=null->rc=-;
- null->sum=;
- }
- void push_rev(lct* x)
- {
- if(x==null) return;
- x->rev=!x->rev;
- swap(x->son[],x->son[]);
- swap(x->lc,x->rc);
- }
- void push_setc(lct* x,int setc)
- {
- if(x==null) return;
- x->c=setc;
- x->setc=setc;
- x->lc=setc;
- x->rc=setc;
- x->sum=;
- }
- void pushdown(lct* x)
- {
- if(x->setc!=-)
- {
- push_setc(x->son[],x->setc);
- push_setc(x->son[],x->setc);
- x->setc=-;
- }
- if(x->rev)
- {
- push_rev(x->son[]);
- push_rev(x->son[]);
- x->rev=;
- }
- }
- void pushup(lct* x)
- {
- if(x==null) return;
- x->sum=;
- if(x->son[]!=null)
- {
- x->sum+=x->son[]->sum;
- if(x->son[]->rc==x->c) x->sum--;
- }
- if(x->son[]!=null)
- {
- x->sum+=x->son[]->sum;
- if(x->son[]->lc==x->c) x->sum--;
- }
- x->lc=x->c;
- if(x->son[]!=null) x->lc=x->son[]->lc;
- x->rc=x->c;
- if(x->son[]!=null) x->rc=x->son[]->rc;
- }
- bool Same(lct* x,lct* &y) //判断x和x的父亲是否在同一树里
- {
- return (y=x->fa)!=null&&(y->son[]==x||y->son[]==x);
- }
- void Rotate(lct* x,int d) //翻转
- {
- lct* y=x->fa; //x的父亲
- y->son[d^]=x->son[d];
- if(x->son[d]!=null) x->son[d]->fa=y; //x的子节点的父亲指向y
- x->fa=y->fa; //连接
- if(y->fa->son[]==y) x->fa->son[]=x;
- else if(y->fa->son[]==y) x->fa->son[]=x;
- x->son[d]=y;
- y->fa=x;
- }
- void Splay(lct* x)
- {
- pushdown(x); //清除标记
- lct* y;
- while(Same(x,y)) //没有到树的最顶点
- {
- pushdown(y);
- pushdown(x);
- Rotate(x,y->son[]==x); //翻转
- pushup(y);
- pushup(x);
- }
- }
- lct* Access(lct* u) //打通路径,返回的是根
- {
- lct *v=null;
- for(;u!=null;u=u->fa)
- {
- Splay(u);
- u->son[]=v;
- pushup(v=u);
- }
- return v;
- }
- lct* GetRoot(lct* x) //得到根
- {
- for(x=Access(x);pushdown(x),x->son[]!=null;x=x->son[]) pushup(x);
- return x;
- }
- void MakeRoot(lct* x) //使x成为根
- {
- Access(x);
- Splay(x);
- push_rev(x);
- }
- void Link(lct* x,lct* y) //连接两个点
- {
- MakeRoot(x);
- x->fa=y;
- Access(x);
- }
- void Cut(lct* x,lct* y) //断开两个点
- {
- MakeRoot(x);
- Access(y);
- Splay(y);
- y->son[]->fa=null;
- y->son[]=null;
- }
- void SetC(lct* x,lct* y,int setc)
- {
- MakeRoot(x);
- push_setc(Access(y),setc);
- }
- int Query(lct* x,lct* y)
- {
- MakeRoot(x);
- Access(y);
- Splay(y);
- return y->sum;
- }
- }A;
- int main()
- {
- scanf("%d%d",&N,&M);
- for(int i=;i<=N;i++) scanf("%d",&C[i]);
- A.init(N);
- int x,y;
- for(int i=;i<N;i++)
- {
- scanf("%d%d",&x,&y);
- A.Link(A.data+x,A.data+y);
- }
- char op[];
- int c;
- while(M--)
- {
- scanf("%s%d%d",op,&x,&y);
- if(op[]=='C') scanf("%d",&c);
- if(op[]=='C') A.SetC(A.data+x,A.data+y,c);
- else printf("%d\n",A.Query(A.data+x,A.data+y));
- }
- return ;
- }
bzoj2243-染色(动态树lct)的更多相关文章
- hdu 5398 动态树LCT
GCD Tree Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Su ...
- hdu 5002 (动态树lct)
Tree Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submi ...
- 动态树LCT小结
最开始看动态树不知道找了多少资料,总感觉不能完全理解.但其实理解了就是那么一回事...动态树在某种意思上来说跟树链剖分很相似,都是为了解决序列问题,树链剖分由于树的形态是不变的,所以可以通过预处理节点 ...
- bzoj2049-洞穴勘测(动态树lct模板题)
Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好 ...
- [模板] 动态树/LCT
简介 LCT是一种数据结构, 可以维护树的动态加边, 删边, 维护链上信息(满足结合律), 单次操作时间复杂度 \(O(\log n)\).(不会证) 思想类似树链剖分, 因为splay可以换根, 用 ...
- 动态树LCT(Link-cut-tree)总结+模板题+各种题目
一.理解LCT的工作原理 先看一道例题: 让你维护一棵给定的树,需要支持下面两种操作: Change x val: 令x点的点权变为val Query x y: 计算x,y之间的唯一的最短路径的点 ...
- SPOJ OTOCI 动态树 LCT
SPOJ OTOCI 裸的动态树问题. 回顾一下我们对树的认识. 最初,它是一个连通的无向的无环的图,然后我们发现由一个根出发进行BFS 会出现层次分明的树状图形. 然后根据树的递归和层次性质,我们得 ...
- HDU 4718 The LCIS on the Tree (动态树LCT)
The LCIS on the Tree Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Oth ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 (动态树LCT)
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 2843 Solved: 1519[Submi ...
- HDU 5002 Tree(动态树LCT)(2014 ACM/ICPC Asia Regional Anshan Online)
Problem Description You are given a tree with N nodes which are numbered by integers 1..N. Each node ...
随机推荐
- mysql c haracter
基本概念 • 字符(Character)是指人类语言中最小的表义符号.例如’A'.’B'等:• 给定一系列字符,对每个字符赋予一个数值,用数值来代表对应的字符,这一数值就是字符的编码(Encoding ...
- 20 个非常棒的jQuery内容滑动插件
Wow Slider WOW Slider是一款小巧易用的网页滑块设计.该软件内置大量的模版和工具,让你轻松设计出完美的视觉效果.他还可以帮助用户在短时间内创造出梦幻般的滑块,而无需编码和图像编辑, ...
- leetcode_question_57 Insert Interval
Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessa ...
- [Redux] Passing the Store Down Implicitly via Context
We have to write a lot of boiler plate code to pass this chore down as a prop. But there is another ...
- eclipse注释模板修改
http://swiftlet.net/archives/1199 以下为模板文件 <?xml version="1.0" encoding="UTF-8" ...
- Android 编程下 Activity 的创建和应用退出时的销毁
为了确保对应用中 Activity 的创建和销毁状态进行控制,所以就需要一个全局的变量来记录和销毁这些 Activity.这里的大概思路是写一个类继承 Application,并使获取该 Applic ...
- easyui combobox赋值
$('#cc').combobox('setValue','bitem3').combobox('setText','bitem3')
- vc中调用Com组件的方法详解
vc中调用Com组件的方法详解 转载自:网络,来源未知,如有知晓者请告知我.需求:1.创建myCom.dll,该COM只有一个组件,两个接口: IGetRes--方法Hello(), IGet ...
- (二)CSS3应用 - 实现圆角
html <link href="test.css" type="text/css" rel="stylesheet" /> & ...
- Qt历史版本下载
今天找到一个Qt官方下载任意版本的链接,在这里分享给大家~ http://download.qt.io/archive/qt/ 里面有Qt的历史版本 原文链接http://www.donnyblog. ...