[Luogu P3203] [HNOI2010]弹飞绵羊 (LCT维护链的长度)
题面
传送门:洛谷
Solution
这题其实是有类似模型的。
我们先考虑不修改怎么写。考虑这样做:每个点向它跳到的点连一条边,最后肯定会连成一颗以n+1为根的树(我们拿n+1代表被弹出去了)。题目所问的即是某个点到树根的链的长度。
那么,如果我们加上修改,显然,某个点连向的点会发生改变。对于一个能修改边的树,我们可以很自然的想到用LCT维护之。
至于怎么求某条链的长度呢?这也是LCT的基础操作之一,我们只需要先MakeRoot(n+1),然后再Acess(x),splay(x)就可以把这条链拉出来了,我们维护splay的size就好。
如果您看不懂上面这句话,请戳我来学习LCT与原树的对应关系
Code
//Luogu P3203 [HNOI2010]弹飞绵羊
//Jan,9th,2018
//LCT模板题II
#include<iostream>
#include<cstdio>
using namespace std;
long long read()
{
long long x=0,f=1; char c=getchar();
while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
const int N=200000+100;
int n,m;
struct LCT
{
int son[N][2],fa[N],lazy[N],mstack[N],top,size[N];
inline bool isRoot(int x)
{
return x!=son[fa[x]][0] && x!=son[fa[x]][1];
}
inline void update(int x)
{
size[x]=size[son[x][0]]+size[son[x][1]]+1;
}
inline void mirror(int x)
{
lazy[x]=!lazy[x],swap(son[x][0],son[x][1]);
}
inline void pushDown(int x)
{
if(lazy[x]==0) return;
lazy[x]=0;
mirror(son[x][0]),mirror(son[x][1]);
}
inline void rotate(int x,int type)
{
int y=fa[x],z=fa[y];
if(isRoot(y)==false)
son[z][y==son[z][1]]=x;
fa[x]=z;
son[y][!type]=son[x][type],fa[son[x][type]]=y;
son[x][type]=y,fa[y]=x;
update(y),update(x);
}
void splay(int x)
{
mstack[top=1]=x;
for(int i=x;isRoot(i)==false;i=fa[i])
mstack[++top]=fa[i];
for(int i=top;i>=1;i--)
pushDown(mstack[i]);
while(isRoot(x)==false)
{
if(x==son[fa[x]][fa[x]==son[fa[fa[x]]][1]] and isRoot(fa[x])==false)
rotate(fa[x],x==son[fa[x]][0]),
rotate(x,x==son[fa[x]][0]);
else
rotate(x,x==son[fa[x]][0]);
}
}
void Access(int x)
{
for(int t=0;x!=0;t=x,x=fa[x])
splay(x),son[x][1]=t,fa[t]=x,update(x);
}
inline void MakeRoot(int x)
{
Access(x),splay(x);
mirror(x);
}
inline void Link(int x,int y)//x翻为根连向y
{
MakeRoot(x);
fa[x]=y;
}
inline void split(int x,int y)//y为根
{
MakeRoot(x);
Access(y),splay(y);
}
inline void Cut(int x,int y)
{
split(x,y);
son[y][0]=fa[x]=0;
update(y);
}
int Query(int x)
{
MakeRoot(n+1);
Access(x),splay(x);
return size[x]-1;
}
}lct;
int q[N];
int main()
{
n=read();
for(int i=1;i<=n;i++)
q[i]=read(); for(int i=n;i>=1;i--)
if(i+q[i]>n)
lct.Link(i,n+1);
else
lct.Link(i,i+q[i]);
m=read();
for(int i=1;i<=m;i++)
{
int op=read();
if(op==1)
{
int x=read()+1;
printf("%d\n",lct.Query(x));
}
else
{
int x=read()+1,K=read();
if(x+q[x]>n)
lct.Cut(x,n+1);
else
lct.Cut(x,x+q[x]);
q[x]=K;
if(x+q[x]<=n)
lct.Link(x,x+q[x]);
else
lct.Link(x,n+1);
}
}
return 0;
}
[Luogu P3203] [HNOI2010]弹飞绵羊 (LCT维护链的长度)的更多相关文章
- 洛谷P3203 [HNOI2010] 弹飞绵羊 [LCT]
题目传送门 弹飞绵羊 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置, ...
- P3203 [HNOI2010]弹飞绵羊(LCT)
弹飞绵羊 题目传送门 解题思路 LCT. 将每个节点的权值设为\(1\),连接\(i\)和\(i+ki\),被弹飞就连上\(n\),维护权值和\(sum[]\).从\(j\)弹飞需要的次数就是\(sp ...
- 【题解】Luogu P3203 [HNOI2010]弹飞绵羊
原题传送门 这题用Link-Cut-Tree解决,Link-Cut-Tree详解 预处理:从一个点弹到另一个点就在lct里从\(i\)连边到\(i+k_i\),如果绵羊被弹飞了就从\(i\)连边到\( ...
- P3203 [HNOI2010]弹飞绵羊(LCT)
P3203 [HNOI2010]弹飞绵羊 LCT板子 用一个$p[i]$数组维护每个点指向的下个点. 每次修改时cut*1+link*1就解决了 被弹出界时新设一个点,权为0,作为终点表示出界点.其他 ...
- 洛谷 P3203 [HNOI2010]弹飞绵羊 解题报告
P3203 [HNOI2010]弹飞绵羊 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一 ...
- P3203 [HNOI2010]弹飞绵羊 —— 懒标记?分块?LCT?...FAQ orz
好久没写博客了哈,今天来水一篇._(:з」∠)_ 题目 :弹飞绵羊(一道省选题) 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏 ...
- P3203 [HNOI2010]弹飞绵羊 —— 懒标记?分块?
好久没写博客了哈,今天来水一篇._(:з」∠)_ 题目 :弹飞绵羊(一道省选题) 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏 ...
- 洛谷P3203 [HNOI2010]弹飞绵羊(LCT,Splay)
洛谷题目传送门 关于LCT的问题详见我的LCT总结 思路分析 首先分析一下题意.对于每个弹力装置,有且仅有一个位置可以弹到.把这样的一种关系可以视作边. 然后,每个装置一定会往后弹,这不就代表不存在环 ...
- BZOJ2002[Hnoi2010]弹飞绵羊——LCT
题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系 ...
随机推荐
- gRPC-微服务间通信实践
微服务间通信常见的两种方式 由于微服务架构慢慢被更多人使用后,迎面而来的问题是如何做好微服务间通信的方案.我们先分析下目前最常用的两种服务间通信方案. gRPC(rpc远程调用) 场景:A服务主动发起 ...
- 剑指offer-链表&数组
1.圆圈中最后剩下的数 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此.HF作为牛客的资深元老,自然也准备了一些小游戏.其中,有个游戏是这样的:首先,让小朋友们围成一个大圈. ...
- MacOS如何正确配置Idea自带Maven插件的环境变量?(亲测)
背景 安装了IDEA开发工具,想执行Maven的命令.但是又没有通过自己下载Maven的安装包进行安装,只是想直接使用IDEA自带的Maven插件来执行Maven的各种命令.由于刚开始使用macos对 ...
- HarmonyOS 润和 HiSpark开发套件 免费领!
让人期盼已久的HarmonyOS 2.0终于在9月10日正式上线啦! 这是一件让众多开发者关注的大事件! 相信不少开发者都已经迫不及待的想上手实操了, 为了满足大家的好奇心, 也希望能有更多开发者了解 ...
- 证明RSA算法在明文和公私钥中N不互质情况下仍然成立
关于RSA的基础过程介绍 下文中的 k 代表自然数常数,不同句子,公式中不一定代表同一个数 之前接触RSA,没有过多的思考证明过程,今天有感而发,推到了一遍 假设公钥 (e, N) , 私钥 (d, ...
- RHSA-2017:2679-重要: 内核 安全更新(需要重启、存在EXP、代码执行)
[root@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) 修复命令: 使用root账号登陆She ...
- 许嵩新歌《放肆》发布 && 递归 + Stream+Lambda相遇成树
一.<放肆>如约而至 今早5:00在迷迷糊糊中醒来,打开手机一看,许嵩又发新歌了,名字叫做<放肆>,澎湃的旋律,依旧古典高雅的用词,这个大男孩,已经不像12年那时候发些伤感非主 ...
- object-fit 详解
contain 被替换的内容将被缩放,以在填充元素的内容框时保持其宽高比. 整个对象在填充盒子的同时保留其长宽比,因此如果宽高比与框的宽高比不匹配,该对象将被添加"黑边". cov ...
- 如何把base64格式的图片上传到到阿里云oss c#版
今天碰到需要把canvas上的的图片转存到阿里云oss,于是百度了半天,一个能打的答案都没有.怒了,自己搞起. 代码超级简单,需要先引入nuget 中啊里云的oss api 1 byte[] arr ...
- 基于python实现二叉树的遍历
""" 二叉树实践: 用递归构建树的遍历 # 思路分析 -- 1.使用链式存储,一个Node表示一个数的节点 -- 2.节点考虑使用两个属性变量,分别表示左连接右连接 & ...