[BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree)
[BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree)
题面
某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞。绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞。为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数。
分析
首先把所有点编号+1,建立虚拟节点n+1表示被弹飞。如果i+ki>n就连边(i,n+1)否则连边(i,i+ki)。
修改就是先删边再加边
查询其实就是查询x到n+1的路径长度.split(x,n+1)后的子树大小-1即为答案
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 200000
using namespace std;
struct link_cut_tree{
#define lson(x) (tree[x].ch[0])
#define rson(x) (tree[x].ch[1])
#define fa(x) (tree[x].fa)
struct node{
int ch[2];
int fa;
int sz;
int revm;
}tree[maxn+5];
inline bool is_root(int x){
return !(lson(fa(x))==x||rson(fa(x))==x);
}
inline int check(int x){
return rson(fa(x))==x;
}
void push_up(int x){
tree[x].sz=tree[lson(x)].sz+tree[rson(x)].sz+1;
}
void reverse(int x){
swap(lson(x),rson(x));
tree[x].revm^=1;
}
void push_down(int x){
if(tree[x].revm){
reverse(lson(x));
reverse(rson(x));
tree[x].revm=0;
}
}
void push_down_all(int x){
if(!is_root(x)) push_down_all(fa(x));
push_down(x);
}
void rotate(int x){
int y=fa(x),z=fa(y),k=check(x),w=tree[x].ch[k^1];
tree[y].ch[k]=w;
tree[w].fa=y;
if(!is_root(y)) tree[z].ch[check(y)]=x;
tree[x].fa=z;
tree[x].ch[k^1]=y;
tree[y].fa=x;
push_up(y);
push_up(x);
}
void splay(int x){
push_down_all(x);
while(!is_root(x)){
int y=fa(x);
if(!is_root(y)){
if(check(x)==check(y)) rotate(y);
else rotate(x);
}
rotate(x);
}
push_up(x);
}
void access(int x){
for(int y=0;x;y=x,x=fa(x)){
splay(x);
rson(x)=y;
push_up(x);
}
}
void make_root(int x){
access(x);
splay(x);
reverse(x);
}
void split(int x,int y){
make_root(x);
access(y);
splay(y);
}
void link(int x,int y){
make_root(x);
fa(x)=y;
}
void cut(int x,int y){
split(x,y);
lson(y)=fa(x)=0;
push_up(y);
}
int query(int x,int y){//查询x到y的路径长度,即split出来的子树大小-1
split(x,y);
return tree[y].sz-1;
}
}T;
int n,m;
int a[maxn+5];
//虚拟节点n+1表示被弹飞
inline int get_nex(int x,int k){//找到被弹到的节点
if(x+k<=n) return x+k;
else return n+1;
}
int main(){
int cmd,x,k;
scanf("%d",&n);
for(int i=1;i<=n+1;i++) T.tree[i].sz=1;
// T.link(4,5);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
T.link(i,get_nex(i,a[i]));
}
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d",&cmd);
if(cmd==1){
scanf("%d",&x);
x++;
printf("%d\n",T.query(x,n+1));//查询x到n+1路径长度
}else{
scanf("%d %d",&x,&k);
x++;
T.cut(x,get_nex(x,a[x]));
a[x]=k;
T.link(x,get_nex(x,a[x]));
}
}
}
[BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree)的更多相关文章
- bzoj 2002 Bounce 弹飞绵羊
bzoj 2002 Bounce 弹飞绵羊 设一个虚拟节点表示被弹飞,则每个点的后继点是唯一确定的,每个点向它的后继点连边,就形成了一颗树. 询问就是问某个节点到虚拟节点的路径长度,修改就删除原来向后 ...
- BZOJ 2002 Bounce 弹飞绵羊 (分块或动态树)
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 13768 Solved: 6989[Subm ...
- BZOJ 2002 Bounce 弹飞绵羊 —— 分块算法
题目链接:https://vjudge.net/problem/HYSBZ-2002 2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Li ...
- bzoj 2002 Bounce 弹飞绵羊(分块)
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 11202 Solved: 5698[Subm ...
- 【bzoj 2002】弹飞绵羊
Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置 ...
- 2002. [HNOI2010]弹飞绵羊【LCT】
Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置 ...
- BZOJ.2002.Bounce 弹飞绵羊(LCT)
题目链接 从一个点只能往后跳,即后继状态只有一个,那么拿nxt[x]做fa[x]啊!这样就成了一棵树,从每个点开始的答案是它到所在树的根节点的距离. nxt[]的更改即动态修改树边,用LCT即可. 这 ...
- BZOJ 2002 HNOI2010 弹飞羊 块
标题效果,LCT解释版本:见 http://blog.csdn.net/popoqqq/article/details/38849471 如今,用一只手滑动块,并再次改写这个问题0.0 块短啊 将进入 ...
- P3203 [HNOI2010]弹飞绵羊(LCT)
P3203 [HNOI2010]弹飞绵羊 LCT板子 用一个$p[i]$数组维护每个点指向的下个点. 每次修改时cut*1+link*1就解决了 被弹出界时新设一个点,权为0,作为终点表示出界点.其他 ...
随机推荐
- Quartz.NET 作业调度(一):Test
Quartz.NET 是一个开源的作业调度框架,是 Java 作业调度框架 Quartz 的.NET 版本,对于周期性的任务,其作业和触发器的结合,极大的简化了代码的编写,大多时候我们只需要关注作业本 ...
- boost1.59编译安装
boost 1.59.0编译及使用 1.下载: 网址:http://sourceforge.net/projects/boost/files/boost/1.59.0/ 选择:boost_1_59_0 ...
- .net 查壳工具
请问大神.NET查壳工具都有哪些? 已知的有DotNet Id 除了这个还有别的吗?脱MAXTOCODE发现是双壳.脱掉第一层还有一层,DotNet Id检测没壳了,但是反编译还是加密状态. 用 ...
- React 番外篇
小技巧:如果我们想了解一门技术,不知道如何学习,那就在 BOSS 直聘上,来看看对这门技术的要求 这篇给大家讲的是 React 1.0 的初始版本,仅仅是让大家有个了解,毕竟回顾历史,我们才能找到他最 ...
- iOS即时通讯之CocoaAsyncSocket源码解析三
原文 前言 本文实例Github地址:即时通讯的数据粘包.断包处理实例. 本文旨以实例的方式,使用CocoaAsyncSocket这个框架进行数据封包和拆包.来解决频繁的数据发送下,导致的数据粘包.以 ...
- defer
在Go语言的函数中return语句在底层并不是原子操作,它分为给返回值赋值和RET指令两步.而defer语句执行的时机就在返回值赋值操作后,RET指令执行前.具体如下图所示: 在defer函数定义时, ...
- Transfer 穿梭框
基础用法 Transfer 的数据通过 data 属性传入.数据需要是一个对象数组,每个对象有以下属性:key 为数据的唯一性标识,label为显示文本,disabled 表示该项数据是否禁止转移.目 ...
- 小D课堂 - 零基础入门SpringBoot2.X到实战_第14节 高级篇幅之SpringBoot多环境配置_59、SpringBoot多环境配置介绍和项目实战
笔记 1.SpringBoot多环境配置介绍和项目实战(核心知识) 简介:SpringBoot介绍多环境配置和使用场景 1.不同环境使用不同配置 例如数据库配置,在开发的时候, ...
- 工程变更(ENGINEERING CHANGE)
工程变更(ENGINEERING CHANGE)是企业活动重要的管制项目之一,依照实施的时间.目的不同,其管制细分如下: ECN (ENGINEERING CHANGE NOTICE)工程变更通知: ...
- 使用 QQ 邮箱发送邮件报错:java.net.SocketTimeoutException: Read timed out. Failed messages: javax.mail.MessagingException: Exception reading response
使用 QQ 邮箱发送邮件报错:java.net.SocketTimeoutException: Read timed out. Failed messages: javax.mail.Messagin ...