Description:

小Y家里有一个大森林,里面有n棵树,编号从1到n

0 l r 表示将第 l 棵树到第 r 棵树的生长节点下面长出一个子节点,子节点的标号为上一个 0 号操作叶子标号加 1(例如,第一个 0 号操作产生的子节点标号为 2), l 到 r 之间的树长出的节点标号都相同。保证 1<=l<=r<=n 。

1 l r x 表示将第 l 棵树到第 r 棵树的生长节点改到标号为 x 的节点。对于 i (l<=i<=r)这棵树,如果标号 x的点不在其中,那么这个操作对该树不产生影响。保证 1<=l<=r<=n , x 不超过当前所有树中节点最大的标号。

2 x u v 询问第 x 棵树中节点 u 到节点 v 点的距离,也就是在第 x 棵树中从节点 u 和节点 v 的最短路上边的数量。保证1<=x<=n,这棵树中节点 u 和节点 v 存在。

Hint:

$ N<=105,M<=2*105 $

Solution:

一开始想到线段树套LCT,然而标记无法下传

考虑朴素做法,每个节点用LCT维护一片森林,空间显然无法承受

这时我们需要转换思路

因为题目没有强制在线,所以我们可以只维护一颗”树“,然后按顺序处理1、2操作

每次1操作直接把该生长节点的子树”嫁接“到另一个生长节点

为了保证复杂度,我们需要在生长节点处开一个虚点,这样就不需要多点换父亲了

2操作直接用求个LCA就行了

#include<bits/stdc++.h>
using namespace std;
const int mxn=3e5+5;
struct Q {
int pos,id,x,y,qr;
}q[mxn];
int n,m,p,s,tot,cnt,sum;
int t[mxn],lp[mxn],rp[mxn],bl[mxn],fa[mxn],ch[mxn][2],ans[mxn],val[mxn]; int cmp(Q x,Q y) {
return x.pos==y.pos?x.id<y.id:x.pos<y.pos;
} namespace lct {
int isnotrt(int x) {
return ch[fa[x]][0]==x||ch[fa[x]][1]==x;
}
void push_up(int x) {
t[x]=t[ch[x][0]]+t[ch[x][1]]+val[x];
}
void rotate(int x) {
int y=fa[x],z=fa[y],tp=ch[y][1]==x;
if(isnotrt(y)) ch[z][ch[z][1]==y]=x; fa[x]=z;
ch[y][tp]=ch[x][tp^1]; fa[ch[x][tp^1]]=y;
ch[x][tp^1]=y; fa[y]=x;
push_up(y),push_up(x);
}
void splay(int x) {
while(isnotrt(x)) {
int y=fa[x],z=fa[y];
if(isnotrt(y))
(ch[y][1]==x)^(ch[z][1]==y)?rotate(x):rotate(y);
rotate(x);
}
}
int access(int x) {
int y;
for(y=0;x;x=fa[y=x])
splay(x),ch[x][1]=y,push_up(x);
return y;
}
void link(int x,int y) {
splay(x); fa[x]=y;
}
void cut(int x) {
access(x); splay(x);
ch[x][0]=fa[ch[x][0]]=0;
push_up(x);
}
}
using namespace lct; int main()
{
scanf("%d%d",&n,&m); int res,lca,opt,l,r,x,y;
p=tot=val[1]=t[1]=lp[1]=bl[1]=1; rp[1]=n; int now=2; link(++p,1);
for(int i=1;i<=m;++i) {
scanf("%d",&opt);
if(opt==0) {
scanf("%d%d",&l,&r);
bl[++tot]=++p; link(p,now); //每次把新节点直接长在最近更新的生成节点,考虑这样为什么不会错,因为实点之间的虚点不会影响答案
lp[tot]=l,rp[tot]=r;
val[p]=t[p]=1;
}
else if(opt==1) {
scanf("%d%d%d",&l,&r,&x);
l=max(l,lp[x]); r=min(r,rp[x]);
if(l>r) continue;//去掉无用的区间
link(++p,now);
q[++s]=(Q){l,i,p,bl[x],0};
q[++s]=(Q){r+1,i,p,now,0};
now=p;
}
else scanf("%d%d%d",&l,&x,&y),q[++s]=(Q){l,i,bl[x],bl[y],++sum};
}
sort(q+1,q+s+1,cmp);
for(int i=1;i<=s;++i) {
if(q[i].qr>0) {
access(q[i].x); splay(q[i].x); res=t[q[i].x]; //因为这题规定根为1,所以我们不能makert
lca=access(q[i].y); splay(q[i].y); res+=t[q[i].y];
access(lca); ans[q[i].ss]=res-t[lca]*2;
}
else cut(q[i].x),link(q[i].x,q[i].y);
}
for(int i=1;i<=sum;++i) printf("%d\n",ans[i]);
return 0;
}

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

  1. [ZJOI2016]大森林(LCT)

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

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

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

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

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

  4. bzoj 4573: [Zjoi2016]大森林

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

  5. P3348 [ZJOI2016]大森林

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

  6. 【LuoguP3348】[ZJOI2016]大森林

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

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

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

  8. BZOJ4573 : [Zjoi2016]大森林

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

  9. ●洛谷P3348 [ZJOI2016]大森林

    题链: https://www.luogu.org/problemnew/show/P3348 题解: LCT,神题 首先有这么一个结论: 每次的1操作(改变生长点操作),一定只会会对连续的一段区间产 ...

随机推荐

  1. 矩阵乘法的运算量计算(华为OJ)

    题目地址: https://www.nowcoder.com/practice/15e41630514445719a942e004edc0a5b?tpId=37&&tqId=21293 ...

  2. Quartz.NET作业调度框架的简单应用

    概述 Quartz.NET是一个开源的作业调度框架,非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等. Quartz.NET允许开发人员根据时间间隔(或天)来调度作业.它实现了 ...

  3. java web获取请求体内容

    Java Web中如何获取请求体内容呢? 我们知道请求方式分为两种:Get,Post. /*** * Compatible with GET and POST * * @param request * ...

  4. centos7 yum install redis

    直接yum 安装的redis 不是最新版本 yum install redis 如果要安装最新的redis,需要安装Remi的软件源,官网地址:http://rpms.famillecollet.co ...

  5. 【译】如何使用Vue捕获网络摄像头视频

    几个月前,我一直关注着比特币的爆发并且在GDAX网站上注册账号.在注册验证的过程中,网站提示要通过计算机的网络摄像头提交我自己的一张照片作为照片ID.这是一个很酷的做法,让我思考一个问题:在网络浏览器 ...

  6. selenium课程笔记

    selenium课程笔记第一天(2017-7-1) 一.配置火狐浏览器 运行:firefox.exe -p -no -remote selenium课程笔记第二天 用Eclipse+java+sele ...

  7. Maya mayapy.exe 安装 Cython,编译 pyd

    Maya mayapy.exe 安装 Cython,编译 pyd 前言 在 Python 2.7 cython cythonize py 编译成 pyd 谈谈那些坑 中最后提到,使用  VCForPy ...

  8. Java中菜单的实现以及画实线与画虚线之间的自由转化

    1.Java画线 1 import java.awt.Color; import java.awt.Container; import java.awt.Graphics; import java.a ...

  9. CentOS 7开机出现welcome to emergency mode! 解决方法

    CentOS7.3昨天用的还好好的的,但是今天开机提示如下(如图提示):welcome to emergency mode!after logging in ,type “journalctl -xb ...

  10. 大家的备忘录——xpage_在线引用jQuery

    <xp:this.resources> <xp:dojoModule name="dojo.fx"></xp:dojoModule> <x ...