题目描述

小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. lumen 5.6 设置APP_KEY为32位长的随机字符串

    在 App\Console\Commands下 添加以下内容的KeyGenerateCommand.php文件 <?php namespace App\Console\Commands; use ...

  2. mybatis一级缓存详解

    mybatis缓存分为一级缓存,二级缓存和自定义缓存.本文重点讲解一级缓存 一:前言 在介绍缓存之前,先了解下mybatis的几个核心概念: * SqlSession:代表和数据库的一次会话,向用户提 ...

  3. day 7-18 mysql case when语句

    概述: sql语句中的case语句与高级语言中的switch语句,是标准sql的语法,适用于一个条件判断有多种值的情况下分别执行不同的操作. 首先,让我们看一下CASE的语法.在一般的SELECT中, ...

  4. JQ remove()方法实现似收货地址逐一删除的效果

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. qtp 自动化测试--点滴 菜单没有了,有些控件运行时找不到

    test项目页签下-没有了 菜单栏:file edit view insert 看不到了 1 解决:在startpage标签下-tool-option-点击 restore layout-确定 2 菜 ...

  6. 解决 Redis 只读不可写的问题

    本文转载:https://blog.csdn.net/han_cui/article/details/54767208?tdsourcetag=s_pcqq_aiomsg 解决 Redis 只读不可写 ...

  7. ABP 番外篇-容器

    一. @using YD.CloudTimetable.Web.Areas.AppAreaName.Startup @{ ViewBag.CurrentPageName = AppAreaNamePa ...

  8. LODOP设置打印机不存在不打印

    LODOP中打印机的选择有优先级的存在,如果程序中指定的是错误的打印机,那么会走下一个优先级,这样,就可能存在选择了打印机无效,从默认打印机打印出来了,可以在代码里加判断避免这一点. 打印机优先级简介 ...

  9. SharePoint 2013 使用 RBS 功能将二进制大型对象 BLOB 存储在内容数据库外部。

    为每个内容数据库设置 BLOB 存储   启用并配置 FILESTREAM 之后,请按照以下过程在文件系统中设置 BLOB 存储.必须为要对其使用 RBS 的每个内容数据库设置 BLOB 存储. 设置 ...

  10. codeforces-962-c

    题意:给你一个数,问从中删除某几位数字后重新组成的数字是否是某个数的平方: 解题思路:数据小,dfs直接搜,每位数只有两种选择,要或者不要 #include<iostream> #incl ...