解析:增加三个变量lc(最左边的颜色),rc(最右边的颜色),sum(连续相同颜色区间段数)。然后就是区间合并的搞法。我就不详细解释了,估计你已经想到

如何做了。

代码

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<string>
  4. #include<vector>
  5. #include<algorithm>
  6. using namespace std;
  7. const int maxn=;
  8. int N,M,C[maxn];
  9. struct lct
  10. {
  11. lct *fa,*son[];
  12. int rev,c,setc,lc,rc,sum;
  13. };
  14. struct LCT
  15. {
  16. lct data[maxn];
  17. lct *null;
  18. void init(int Size=maxn-) //初始化
  19. {
  20. null=data; //null指向首元素
  21. for(int i=;i<=Size;i++)
  22. {
  23. data[i].son[]=data[i].son[]=data[i].fa=null;
  24. data[i].rev=;
  25. data[i].c=data[i].lc=data[i].rc=C[i];
  26. data[i].setc=-;
  27. data[i].sum=;
  28. }
  29. null->c=null->lc=null->rc=-;
  30. null->sum=;
  31. }
  32. void push_rev(lct* x)
  33. {
  34. if(x==null) return;
  35. x->rev=!x->rev;
  36. swap(x->son[],x->son[]);
  37. swap(x->lc,x->rc);
  38. }
  39. void push_setc(lct* x,int setc)
  40. {
  41. if(x==null) return;
  42. x->c=setc;
  43. x->setc=setc;
  44. x->lc=setc;
  45. x->rc=setc;
  46. x->sum=;
  47. }
  48. void pushdown(lct* x)
  49. {
  50. if(x->setc!=-)
  51. {
  52. push_setc(x->son[],x->setc);
  53. push_setc(x->son[],x->setc);
  54. x->setc=-;
  55. }
  56. if(x->rev)
  57. {
  58. push_rev(x->son[]);
  59. push_rev(x->son[]);
  60. x->rev=;
  61. }
  62. }
  63. void pushup(lct* x)
  64. {
  65. if(x==null) return;
  66. x->sum=;
  67. if(x->son[]!=null)
  68. {
  69. x->sum+=x->son[]->sum;
  70. if(x->son[]->rc==x->c) x->sum--;
  71. }
  72. if(x->son[]!=null)
  73. {
  74. x->sum+=x->son[]->sum;
  75. if(x->son[]->lc==x->c) x->sum--;
  76. }
  77. x->lc=x->c;
  78. if(x->son[]!=null) x->lc=x->son[]->lc;
  79. x->rc=x->c;
  80. if(x->son[]!=null) x->rc=x->son[]->rc;
  81. }
  82. bool Same(lct* x,lct* &y) //判断x和x的父亲是否在同一树里
  83. {
  84. return (y=x->fa)!=null&&(y->son[]==x||y->son[]==x);
  85. }
  86. void Rotate(lct* x,int d) //翻转
  87. {
  88. lct* y=x->fa; //x的父亲
  89. y->son[d^]=x->son[d];
  90. if(x->son[d]!=null) x->son[d]->fa=y; //x的子节点的父亲指向y
  91. x->fa=y->fa; //连接
  92. if(y->fa->son[]==y) x->fa->son[]=x;
  93. else if(y->fa->son[]==y) x->fa->son[]=x;
  94. x->son[d]=y;
  95. y->fa=x;
  96. }
  97. void Splay(lct* x)
  98. {
  99. pushdown(x); //清除标记
  100. lct* y;
  101. while(Same(x,y)) //没有到树的最顶点
  102. {
  103. pushdown(y);
  104. pushdown(x);
  105. Rotate(x,y->son[]==x); //翻转
  106. pushup(y);
  107. pushup(x);
  108. }
  109. }
  110. lct* Access(lct* u) //打通路径,返回的是根
  111. {
  112. lct *v=null;
  113. for(;u!=null;u=u->fa)
  114. {
  115. Splay(u);
  116. u->son[]=v;
  117. pushup(v=u);
  118. }
  119. return v;
  120. }
  121. lct* GetRoot(lct* x) //得到根
  122. {
  123. for(x=Access(x);pushdown(x),x->son[]!=null;x=x->son[]) pushup(x);
  124. return x;
  125. }
  126. void MakeRoot(lct* x) //使x成为根
  127. {
  128. Access(x);
  129. Splay(x);
  130. push_rev(x);
  131. }
  132. void Link(lct* x,lct* y) //连接两个点
  133. {
  134. MakeRoot(x);
  135. x->fa=y;
  136. Access(x);
  137. }
  138. void Cut(lct* x,lct* y) //断开两个点
  139. {
  140. MakeRoot(x);
  141. Access(y);
  142. Splay(y);
  143. y->son[]->fa=null;
  144. y->son[]=null;
  145. }
  146. void SetC(lct* x,lct* y,int setc)
  147. {
  148. MakeRoot(x);
  149. push_setc(Access(y),setc);
  150. }
  151. int Query(lct* x,lct* y)
  152. {
  153. MakeRoot(x);
  154. Access(y);
  155. Splay(y);
  156. return y->sum;
  157. }
  158. }A;
  159. int main()
  160. {
  161. scanf("%d%d",&N,&M);
  162. for(int i=;i<=N;i++) scanf("%d",&C[i]);
  163. A.init(N);
  164. int x,y;
  165. for(int i=;i<N;i++)
  166. {
  167. scanf("%d%d",&x,&y);
  168. A.Link(A.data+x,A.data+y);
  169. }
  170. char op[];
  171. int c;
  172. while(M--)
  173. {
  174. scanf("%s%d%d",op,&x,&y);
  175. if(op[]=='C') scanf("%d",&c);
  176. if(op[]=='C') A.SetC(A.data+x,A.data+y,c);
  177. else printf("%d\n",A.Query(A.data+x,A.data+y));
  178. }
  179. return ;
  180. }

bzoj2243-染色(动态树lct)的更多相关文章

  1. hdu 5398 动态树LCT

    GCD Tree Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Su ...

  2. hdu 5002 (动态树lct)

    Tree Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  3. 动态树LCT小结

    最开始看动态树不知道找了多少资料,总感觉不能完全理解.但其实理解了就是那么一回事...动态树在某种意思上来说跟树链剖分很相似,都是为了解决序列问题,树链剖分由于树的形态是不变的,所以可以通过预处理节点 ...

  4. bzoj2049-洞穴勘测(动态树lct模板题)

    Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好 ...

  5. [模板] 动态树/LCT

    简介 LCT是一种数据结构, 可以维护树的动态加边, 删边, 维护链上信息(满足结合律), 单次操作时间复杂度 \(O(\log n)\).(不会证) 思想类似树链剖分, 因为splay可以换根, 用 ...

  6. 动态树LCT(Link-cut-tree)总结+模板题+各种题目

    一.理解LCT的工作原理 先看一道例题: 让你维护一棵给定的树,需要支持下面两种操作: Change x val:  令x点的点权变为val Query x y:  计算x,y之间的唯一的最短路径的点 ...

  7. SPOJ OTOCI 动态树 LCT

    SPOJ OTOCI 裸的动态树问题. 回顾一下我们对树的认识. 最初,它是一个连通的无向的无环的图,然后我们发现由一个根出发进行BFS 会出现层次分明的树状图形. 然后根据树的递归和层次性质,我们得 ...

  8. 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 ...

  9. BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 (动态树LCT)

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 2843  Solved: 1519[Submi ...

  10. 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 ...

随机推荐

  1. mysql c haracter

    基本概念 • 字符(Character)是指人类语言中最小的表义符号.例如’A'.’B'等:• 给定一系列字符,对每个字符赋予一个数值,用数值来代表对应的字符,这一数值就是字符的编码(Encoding ...

  2. 20 个非常棒的jQuery内容滑动插件

    Wow Slider  WOW Slider是一款小巧易用的网页滑块设计.该软件内置大量的模版和工具,让你轻松设计出完美的视觉效果.他还可以帮助用户在短时间内创造出梦幻般的滑块,而无需编码和图像编辑, ...

  3. leetcode_question_57 Insert Interval

    Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessa ...

  4. [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 ...

  5. eclipse注释模板修改

    http://swiftlet.net/archives/1199 以下为模板文件 <?xml version="1.0" encoding="UTF-8" ...

  6. Android 编程下 Activity 的创建和应用退出时的销毁

    为了确保对应用中 Activity 的创建和销毁状态进行控制,所以就需要一个全局的变量来记录和销毁这些 Activity.这里的大概思路是写一个类继承 Application,并使获取该 Applic ...

  7. easyui combobox赋值

    $('#cc').combobox('setValue','bitem3').combobox('setText','bitem3')

  8. vc中调用Com组件的方法详解

    vc中调用Com组件的方法详解 转载自:网络,来源未知,如有知晓者请告知我.需求:1.创建myCom.dll,该COM只有一个组件,两个接口:   IGetRes--方法Hello(),   IGet ...

  9. (二)CSS3应用 - 实现圆角

    html <link href="test.css" type="text/css" rel="stylesheet" /> & ...

  10. Qt历史版本下载

    今天找到一个Qt官方下载任意版本的链接,在这里分享给大家~ http://download.qt.io/archive/qt/ 里面有Qt的历史版本 原文链接http://www.donnyblog. ...