[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)的更多相关文章

  1. bzoj 2002 Bounce 弹飞绵羊

    bzoj 2002 Bounce 弹飞绵羊 设一个虚拟节点表示被弹飞,则每个点的后继点是唯一确定的,每个点向它的后继点连边,就形成了一颗树. 询问就是问某个节点到虚拟节点的路径长度,修改就删除原来向后 ...

  2. BZOJ 2002 Bounce 弹飞绵羊 (分块或动态树)

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 13768  Solved: 6989[Subm ...

  3. BZOJ 2002 Bounce 弹飞绵羊 —— 分块算法

    题目链接:https://vjudge.net/problem/HYSBZ-2002 2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Li ...

  4. bzoj 2002 Bounce 弹飞绵羊(分块)

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 11202  Solved: 5698[Subm ...

  5. 【bzoj 2002】弹飞绵羊

    Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置 ...

  6. 2002. [HNOI2010]弹飞绵羊【LCT】

    Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置 ...

  7. BZOJ.2002.Bounce 弹飞绵羊(LCT)

    题目链接 从一个点只能往后跳,即后继状态只有一个,那么拿nxt[x]做fa[x]啊!这样就成了一棵树,从每个点开始的答案是它到所在树的根节点的距离. nxt[]的更改即动态修改树边,用LCT即可. 这 ...

  8. BZOJ 2002 HNOI2010 弹飞羊 块

    标题效果,LCT解释版本:见 http://blog.csdn.net/popoqqq/article/details/38849471 如今,用一只手滑动块,并再次改写这个问题0.0 块短啊 将进入 ...

  9. P3203 [HNOI2010]弹飞绵羊(LCT)

    P3203 [HNOI2010]弹飞绵羊 LCT板子 用一个$p[i]$数组维护每个点指向的下个点. 每次修改时cut*1+link*1就解决了 被弹出界时新设一个点,权为0,作为终点表示出界点.其他 ...

随机推荐

  1. webpack4 单入口文件配置 多入口文件配置 以及常用的配置

    单入口文件配置 webpack.config.js const path = require('path'); const HtmlWebpackPlugin = require('html-webp ...

  2. js--BOM对象(2)

    一.window对象是整个bom的核心 二.window对象的属性: history:(有关客户访问过的url信息) 方法: back() 加载 history 对象列表中的前一个URL forwar ...

  3. Spring Boot教程(三十六)使用MongoDB数据库(2)

    快速开始使用Spring-data-mongodb 若MongoDB的安装配置采用默认端口,那么在自动配置的情况下,我们不需要做任何参数配置,就能马上连接上本地的MongoDB.下面直接使用sprin ...

  4. Vue_(组件通讯)父组件向子组件传值

    Vue组件 传送门 父组件向子组件传值:父组件通过属性向下传值的方式和子组件通信: 使用步骤: 1.定义组件:现有自定义组件com-a.com-b,com-a是com-b的父组件 2.准备获取数据:c ...

  5. Nginx-rtmp之监听端口的管理

    1. 概述 监听端口属于 server 虚拟主机,它是由 server{} 块下的 listen 配置项决定的. 每监听一个 TCP 端口,都将使用一个独立的 ngx_rtmp_conf_port_t ...

  6. Java-GC 垃圾收集器(HotSpot)

    垃圾收集器为垃圾收集算法的具体实现,是执行垃圾收集算法的,是守护线程. HotSpot 虚拟机采用分代收集(JVM 规范并未对堆区进行划分),将堆分为年轻代和老年代,垃圾收集器也按照这样区分.不过已有 ...

  7. koa 基础(二十二)封装 DB 库 --- 测试

    1.根目录/module/config.js /** * 配置文件 */ var app = { dbUrl: 'mongodb://127.0.0.1:27017/?gssapiServiceNam ...

  8. 一个继承的 DataGridView

    // 允许增加一个 checkbox 列 public class DgvBase : DataGridViewX { protected override void OnColumnAdded(Da ...

  9. 在visual studio工程设置中增加宏定义的方法

    在Solution Explorer中鼠标右键点击其project之后,Configuration(Release)->Configuration Propertity ->C++ -&g ...

  10. 五十五:WTForms表单验证之渲染模板

    此功能看似强大,实则鸡肋 from wtforms import Form, StringField, BooleanField, SelectFieldfrom wtforms.validators ...