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. gitlab报错502及处理

    报错截图: 解决: 1.端口问题 如上面写的815端口,那配置文件的8080端口都改成815端口 之后重新载入配置文件,并开启 gitlab-ctl reconfigure gitlab-ctl st ...

  2. java进阶书籍推荐(不包括基础)

    个人认为看书有两点好处: 能出版出来的书一定是经过反复的思考.雕琢和审核的,因此从专业性的角度来说,一本好书的价值远超其他资料 对着书上的代码自己敲的时候方便 “看完书之后再次提升自我的最好途径是看一 ...

  3. Java基础知识➣网络Socket(六)

    概述 网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来. java.net 包中提供了两种常见的网络协议的支持: TCP:TCP 是传输控制协议的缩写,它保障了两个应用程序之 ...

  4. 【Android】Android WebView 网页输入框获取焦点

    webView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEv ...

  5. vue 中如何对公共css、 js 方法进行单文件统一管理,全局调用

    1.前言 最近,为公司开发交付的一个后台管理系统项目,我使用了 Vue 框架进行开发实践. 模块化.组件化.工程化的开发体验非常好.良好的 api,优雅的设计,对于工程师非常友好. 但是由于模块比较多 ...

  6. BZOJ4025 二分图 分治 并查集 二分图 带权并查集按秩合并

    原文链接http://www.cnblogs.com/zhouzhendong/p/8683831.html 题目传送门 - BZOJ4025 题意 有$n$个点,有$m$条边.有$T$个时间段.其中 ...

  7. Python3爬虫知识点总结

    1.requests获取响应头的方法 eg:获取响应头信息 import requests res = request.head(url).headers print(res)

  8. 009 pandas的Series

    一:创建 1.通过Numpy数组创建 2.属性查看 3.一维数组创建(与numpy的创建一样) 4.通过字典创建 二:应用Numpy数组运算 1.获取值 numpy的数组运算,在Series中都被保留 ...

  9. 011 Linux环境下配置eclipse,以及创建maven工程

    一:maven的安装 1.安装配置maven环境变量 2.验证 二:eclipse的安装 3.解压配置eclipse 4.启动eclipse,必须在虚拟机的eclipse下启动 5.结果 三:修改配置 ...

  10. mybatis提示Invalid bound statement (not found)错误的可能原因

    https://www.cnblogs.com/liaojie970/p/8034525.html