题目描述

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

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

题解

这题太神了,废了我一下午。

看到区间操作,就可以想到差分或者扫描线,我们会发现这题基本没有好的方法去执行批量操作,所以我们要用扫描线。

这道题的操作有,区间生长一个点,区间换父亲。

我们对于每个1操作新建一个虚点,然后把它们串起来,然后把每个0操作长出来的点挂在上一个虚点上,然后一通做完之后的树长这样(白点为虚点,黑点为实点)。

时间从上到下为从早到晚。

对于一个换父亲操作,假如说我们要对最下面的白点对应的换父亲的操作换到右边从上到下第二个黑点上,那么我们可以这样。

可以手玩一下,所有有效节点对应的deep是对的。

然后我们用LCT维护这一过程,求两点

注意判断1操作的作用范围。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 200002
using namespace std;
int tr[N][],fa[N],size[N],w[N],cnt,n,m,tot,top,b[N],L[N],R[N],ji[N],qqq,ans,ans2[N];
inline int rd(){
int x=;char c=getchar();bool f=;
while(!isdigit(c)){if(c=='-')f=;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return f?-x:x;
}
inline bool isroot(int x){return !x||(tr[fa[x]][]!=x&&tr[fa[x]][]!=x);}
inline bool ge(int x){return tr[fa[x]][]==x;}
inline void pushup(int x){size[x]=size[tr[x][]]+size[tr[x][]]+w[x];}
inline void newnode(int x){++cnt;w[cnt]=size[cnt]=x;}
inline void rotate(int x){
int y=fa[x],o=ge(x);
if(isroot(x))return;
tr[y][o]=tr[x][o^];fa[tr[y][o]]=y;
if(!isroot(y))tr[fa[y]][ge(y)]=x;fa[x]=fa[y];
fa[y]=x;tr[x][o^]=y;
pushup(y);pushup(x);
}
inline void splay(int x){
while(!isroot(x)){
int y=fa[x];
if(isroot(y))rotate(x);
else rotate(ge(y)==ge(x)?y:x),rotate(x);
}
}
inline int access(int x){int y=;for(;x;y=x,x=fa[x])splay(x),tr[x][]=y,pushup(x);return y;}//qiu LCA get
inline void link(int x,int y){access(x);splay(x);fa[x]=y;}
inline void cut(int x){access(x);splay(x);fa[tr[x][]]=;tr[x][]=;pushup(x);}
struct node{
int pos,tag,x,y;
inline bool operator <(const node &b)const{
if(pos!=b.pos)return pos<b.pos;
else return tag<b.tag;
}
}a[N<<];
int main(){
n=rd();m=rd();int opt,l,r,k;
newnode();newnode();link(,);
int now=;b[tot=]=;L[tot]=;R[tot]=n;
for(int i=;i<=m;++i){
opt=rd();
if(!opt){
l=rd();r=rd();newnode();
b[++tot]=cnt;L[tot]=l;R[tot]=r;
a[++top]=node{,i-N,cnt,now};
}
else if(opt==){
l=rd();r=rd();k=rd();l=max(l,L[k]);r=min(r,R[k]);
if(l>r)continue;
newnode();link(cnt,now);
a[++top]=node{l,i-N,cnt,b[k]};a[++top]=node{r+,i-N,cnt,now};
now=cnt;
}
else{
k=rd();l=rd();r=rd();ji[i]=++qqq;
a[++top]=node{k,i,b[l],b[r]};
}
}
sort(a+,a+top+);int p=;
for(int i=;i<=n;++i)
for(;a[p].pos==i;++p)
if(a[p].tag<=){cut(a[p].x);link(a[p].x,a[p].y);}
else{
ans=;
access(a[p].x);splay(a[p].x);ans+=size[a[p].x];
int lca=access(a[p].y);splay(a[p].y);ans+=size[a[p].y];
access(lca);splay(lca);ans-=size[lca]*;
ans2[ji[a[p].tag]]=ans;
}
for(int i=;i<=qqq;++i)printf("%d\n",ans2[i]);
return ;
}

[ZJOI2016]大森林(LCT)的更多相关文章

  1. 洛谷P3348 [ZJOI2016]大森林 [LCT]

    传送门 刷了那么久水题之后终于有一题可以来写写博客了. 但是这题太神仙了我还没完全弄懂-- upd:写完博客之后似乎懂了. 思路 首先很容易想到\(O(n^2\log n)\)乘上\(O(\frac{ ...

  2. bzoj 4573: [Zjoi2016]大森林 lct splay

    http://www.lydsy.com/JudgeOnline/problem.php?id=4573 http://blog.csdn.net/lych_cys/article/details/5 ...

  3. [ZJOI2016]大森林

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

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

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

  5. BZOJ4573:[ZJOI2016]大森林——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=4573 https://www.luogu.org/problemnew/show/P3348#sub ...

  6. P3348 [ZJOI2016]大森林

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

  7. bzoj 4573: [Zjoi2016]大森林

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

  8. 【LuoguP3348】[ZJOI2016]大森林

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

  9. UOJ#195. 【ZJOI2016】大♂森林 LCT

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ195.html 题解 首先询问都可以放到最后处理. 对于操作,我们把它差分一下离线下来. 现在的问题就是从 ...

随机推荐

  1. 便捷的ajax请求

    为什么要做这个呢?如果后端给的数据不单有JSON字符串,还有对象呢?这个时候我们就要每个都处理(JSON.parse).万一后端又改了,所有都是对象呢?如此一来我们就需要对我们的ajax进行封装. 这 ...

  2. artTemplate之初印象

    介绍 art-template 是JavaScript模板引擎,是一个简约.超快的模板引擎. 它采用作用域预声明的技术来优化模板渲染速度,从而获得接近 JavaScript 极限的运行性能,并且同时支 ...

  3. 单个源文件下CmakeList.txt

    单个源文件下CmakeList.txt 1. main.c代码 & CmakeLists.txt 文件内容 在任意自己选定的目录下(t1/)编写main.c 与 CmakeLists.txt ...

  4. maven中jar下载失败

    关键词:maven jar 错误描述:反编译时遇到 invalid LOC header (bad signature)的问题 aether-89969cb8-5741-44e3-be2c-74f90 ...

  5. bootstrap.css.map 404

    删除bootstrap.css的最后一行即可: /*# sourceMappingURL=bootstrap.css.map */ English: from bootstrap-theme.css  ...

  6. windows10企业版2016长期服务版激活

    win10 2016 长期服务版的ISO文件中本身就带有KMS激活KEY,不用输入任何KEY,连接网络进入CMD,只要输入:slmgr /skms kms.digiboy.irslmgr /ato这两 ...

  7. shell自定义输入输出 read+echo

    自定义格式输入.输出(244)  输出:echo -e 解释转义字符 -n  回车不换行 \n   新的一行,等同于回车 \t 制表符 \r 回车 \b 回退 baskspace 删除键 演示\n \ ...

  8. Java 基础类型 默认值

    (1)数据库里的列,如果有默认值,不能赋值有业务含义的值. (2)int 默认值 java会分配默认值的额.

  9. jQ append 添加html 及字符串拼接

    如图,我要拼接这样一段html: 点击下边添加按钮,不断添加这段Html html: <div class="x_addtable"> <div class=&q ...

  10. MyBatis基础:MyBatis动态SQL(3)

    1. 概述 MyBatis中动态SQL包括元素: 元素 作用 备注 if 判断语句 单条件分支判断 choose(when.otherwise) 相当于Java中的case when语句 多条件分支判 ...