http://www.lydsy.com/JudgeOnline/problem.php?id=4573

https://www.luogu.org/problemnew/show/P3348#sub

http://uoj.ac/problem/195

https://loj.ac/problem/2092

小Y家里有一个大森林,里面有n棵树,编号从1到n。一开始这些树都只是树苗,只有一个节点,标号为1。这些树都有一个特殊的节点,我们称之为生长节点,这些节点有生长出子节点的能力。

小Y掌握了一种魔法,能让第l棵树到第r棵树的生长节点长出一个子节点。同时她还能修改第l棵树到第r棵树的生长节点。她告诉了你她使用魔法的记录,你能不能管理她家的森林,并且回答她的询问呢?

参考:http://www.sigongzi.org/index.php/archives/LOJ2092.html

思路:

显然我们不能对每棵树LCT维护一下,而且我们对于这棵树的形态还很严格。

那么我们把前一棵树的形态转换为后一棵树的形态,这样就只需要一棵树了。

先考虑对于0操作,实际上我们可以记录每个时刻每个节点在哪一段区间中(代码的L和R就是干这个的),所以我们大可以对所有的树都进行0操作。

对于1操作,和0操作类似,用L和R更新l和r后进行操作。

然后为了能够快捷的更新树,我们建立一个size为0的虚点(这样对于路径长度就不需要修改了),所有的生长操作都在上面进行,这样我们删除的时候cut这个点即可。

对于2操作,事实上两个点一定存在的话,完全可以让0和1操作全部排到它的前面。

实现:

先把所有操作存下来,然后以操作的树为第一关键字,操作编号和顺序为第二关键字排序。

(对于区间修改思考差分,毕竟我们都是对同一棵树操作的。)

然后按树编号从左到右进行操作,对于0和1操作先对虚点清空然后长即可。

查询的时候就是用LCA求最短路的方法一样。

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cstring>
  4. #include<cctype>
  5. #include<cstdio>
  6. #include<vector>
  7. #include<queue>
  8. #include<cmath>
  9. using namespace std;
  10. const int N=4e5+;
  11. struct data{
  12. int pos,id,from,to;
  13. }qry[N];
  14. int n,m,fa[N],tr[N][],val[N],size[N];
  15. int cnt,tot,sum,aux,L[N],R[N],id[N],ans[N];
  16. inline bool cmp(data a,data b){
  17. return a.pos<b.pos||(a.pos==b.pos&&a.id<b.id);
  18. }
  19. inline int read(){
  20. int X=,w=;char ch=;
  21. while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
  22. while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
  23. return w?-X:X;
  24. }
  25. inline bool get(int x){
  26. return tr[fa[x]][]==x;
  27. }
  28. inline bool isroot(int x){
  29. if(!fa[x])return ;
  30. return tr[fa[x]][]!=x&&tr[fa[x]][]!=x;
  31. }
  32. inline void upt(int x){
  33. size[x]=val[x];
  34. if(tr[x][])size[x]+=size[tr[x][]];
  35. if(tr[x][])size[x]+=size[tr[x][]];
  36. }
  37. inline void rotate(int x){
  38. int y=fa[x],z=fa[y],b=tr[y][]==x?tr[x][]:tr[x][];
  39. if(z&&!isroot(y))(tr[z][]==y?tr[z][]:tr[z][])=x;
  40. fa[x]=z;fa[y]=x;b?fa[b]=y:;
  41. if(tr[y][]==x)tr[x][]=y,tr[y][]=b;
  42. else tr[x][]=y,tr[y][]=b;
  43. upt(y);upt(x);
  44. }
  45. inline void splay(int x){
  46. while(!isroot(x)){
  47. if(!isroot(fa[x]))
  48. rotate((get(x)==get(fa[x])?fa[x]:x));
  49. rotate(x);
  50. }
  51. upt(x);
  52. }
  53. inline int access(int x){
  54. int y;
  55. for(y=;x;y=x,x=fa[x]){
  56. splay(x);tr[x][]=y;
  57. if(y)fa[y]=x;
  58. }
  59. return y;
  60. }
  61. inline void link(int x,int y){
  62. splay(y);fa[x]=y;
  63. }
  64. inline void cut(int x){
  65. access(x);splay(x);
  66. if(tr[x][])fa[tr[x][]]=;
  67. tr[x][]=;upt(x);
  68. }
  69. inline void makenode(int x){
  70. val[++sum]=x;size[sum]=x;
  71. }
  72. int main(){
  73. n=read(),m=read();
  74. cnt=;L[cnt]=,R[cnt]=n;id[cnt]=;
  75. makenode();makenode();
  76. aux=sum;
  77. link(aux,id[]);
  78. for(int i=;i<=m;i++){
  79. int op=read();
  80. if(op==){
  81. L[++cnt]=read(),R[cnt]=read();
  82. makenode();
  83. id[cnt]=sum;
  84. qry[++tot]=(data){,i-m,sum,aux};
  85. }
  86. if(op==){
  87. int l=read(),r=read(),x=read();
  88. l=max(l,L[x]);r=min(r,R[x]);
  89. if(l<=r){
  90. makenode();
  91. link(sum,aux);
  92. qry[++tot]=(data){l,i-m,sum,id[x]};
  93. qry[++tot]=(data){r+,i-m,sum,aux};
  94. aux=sum;
  95. }
  96. }
  97. if(op==){
  98. int l=read(),u=read(),v=read();
  99. qry[++tot]=(data){l,i,id[u],id[v]};
  100. }
  101. }
  102. memset(ans,-,sizeof(ans));
  103. sort(qry+,qry+tot+,cmp);
  104. for(int i=,p=;i<=tot;p++){
  105. while(qry[i].pos==p){
  106. if(qry[i].id>){
  107. ans[qry[i].id]=;
  108. access(qry[i].from);splay(qry[i].from);
  109. ans[qry[i].id]+=size[qry[i].from];
  110. int lca=access(qry[i].to);
  111. splay(qry[i].to);
  112. ans[qry[i].id]+=size[qry[i].to];
  113. access(lca);splay(lca);ans[qry[i].id]-=size[lca]*;
  114. }
  115. else{
  116. cut(qry[i].from);link(qry[i].from,qry[i].to);
  117. }
  118. i++;
  119. }
  120. }
  121. for(int i=;i<=m;i++){
  122. if(ans[i]>=)printf("%d\n",ans[i]);
  123. }
  124. return ;
  125. }

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

BZOJ4573:[ZJOI2016]大森林——题解的更多相关文章

  1. BZOJ4573 : [Zjoi2016]大森林

    扫描线,从左到右依次处理每棵树. 用set按时间顺序维护影响了这棵树的所有操作,那么一个点的父亲就是它前面第一个操作1. 用Splay维护树的括号序列,那么两点间的距离就是括号数量减去匹配的括号个数. ...

  2. [BZOJ4573][ZJOI2016]大♂森林

    bzoj luogu uoj sol \(orz\ \ HJT\ \ dalao\)教会我做这道题. 考虑每两个相邻位置的树的差异. 对于一个1操作(更换生长节点),假设区间是\([l,r]\),那么 ...

  3. [ZJOI2016]大森林(LCT)

    题目描述 小Y家里有一个大森林,里面有n棵树,编号从1到n.一开始这些树都只是树苗,只有一个节点,标号为1.这些树都有一个特殊的节点,我们称之为生长节点,这些节点有生长出子节点的能力. 小Y掌握了一种 ...

  4. bzoj 4573: [Zjoi2016]大森林

    Description 小Y家里有一个大森林,里面有n棵树,编号从1到n.一开始这些树都只是树苗,只有一个节点,标号为1.这些树 都有一个特殊的节点,我们称之为生长节点,这些节点有生长出子节点的能力. ...

  5. P3348 [ZJOI2016]大森林

    \(\color{#0066ff}{ 题目描述 }\) 小Y家里有一个大森林,里面有n棵树,编号从1到n.一开始这些树都只是树苗,只有一个节点,标号为1.这些树都有一个特殊的节点,我们称之为生长节点, ...

  6. [ZJOI2016]大森林

    Description: 小Y家里有一个大森林,里面有n棵树,编号从1到n 0 l r 表示将第 l 棵树到第 r 棵树的生长节点下面长出一个子节点,子节点的标号为上一个 0 号操作叶子标号加 1(例 ...

  7. 【刷题】BZOJ 4573 [Zjoi2016]大森林

    Description 小Y家里有一个大森林,里面有n棵树,编号从1到n.一开始这些树都只是树苗,只有一个节点,标号为1.这些树都有一个特殊的节点,我们称之为生长节点,这些节点有生长出子节点的能力.小 ...

  8. 【LuoguP3348】[ZJOI2016]大森林

    题目链接 题目描述 小Y家里有一个大森林,里面有n棵树,编号从1到n.一开始这些树都只是树苗,只有一个节点,标号为1.这些树都有一个特殊的节点,我们称之为生长节点,这些节点有生长出子节点的能力. 小Y ...

  9. 【BZOJ4573】[ZJOI2016] 大森林(LCT)

    点此看题面 大致题意: 有\(n\)棵树,初始各有\(1\)个编号为\(1\)的节点,且其为生长节点.\(3\)种操作:将\([l,r]\)区间内的树增加一个新的编号的节点,修改\([l,r]\)区间 ...

随机推荐

  1. 转:Docker创建centos的LNMP镜像

    转自:http://www.vckai.com/p/29  1. 安装docker 这个就不说了,不会的可以看下我之前的文章<Docker介绍及安装>. 1)启动docker # serv ...

  2. Unity Container中的几种注册方式与示例

    1.实例注册 最简单的注册方式就是实例注册,Unity 容器负责维护对一个类型的单例引用,比如: 有如下的实际类型: namespace ConsoleSample { public class Sa ...

  3. js函数相关高级用法

    一.惰性载入函数(lazy function) 使用场景:当一个函数中的判断分支只用执行一次(第一次调用时执行),后续不会再变化,则可以使用惰性函数来提高性能. var addEvent = func ...

  4. JAVA日志框架概述

            日志用来记录应用的运行状态以及一些关键业务信息,其重要性不言而喻,通常我们借助于现有的日志框架完成日志输出.目前开源的日志框架很多,常见的有log4j.logback等,有时候我们还会 ...

  5. MySQL数据库优化方法

    一.表类型MyISAM 和 InnoDB的区别 作者:Oscarwin链接:https://www.zhihu.com/question/20596402/answer/211492971来源:知乎著 ...

  6. 用Anko和Kotlin实现Android上的对话框和警告提示(KAD 24)

    作者:Antonio Leiva 时间:Mar 9, 2017 原文链接:https://antonioleiva.com/dialogs-android-anko-kotlin/ 借助Builder ...

  7. 第二章 IP协议详解

    第二章 IP协议详解 2.1 IP服务的特点 它为上层协议提供了无状态,无连接,不可靠的服务 名称 简介 优点 缺点 对付缺点的方法 无状态 IP通信双方不同步传输数据的状态信息 无须为保持通信的状态 ...

  8. TensorFlow | ReluGrad input is not finite. Tensor had NaN values

    问题的出现 Question 这个问题是我基于TensorFlow使用CNN训练MNIST数据集的时候遇到的.关键的相关代码是以下这部分: cross_entropy = -tf.reduce_sum ...

  9. iOS-【UIDynamic-UIKit动力学】

    如果看不到图片 可以尝试更换浏览器(推荐Safari ) 0.了解 •Dynamic Animator:动画者,为动力学元素提供物理学相关的能力及动画,同时为这些元素提供相关的上下文,是动力学元素与底 ...

  10. html .net 网页,网站标题添图标

    <link rel="icon" href="../favicon.ico" type="image/x-icon" /> &l ...