[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. mac使用sublime text3打开当前文件夹的终端

    打开sublime text3,同时按住shift+command+p打开扩展列表, 选择Package Control: Install Pageage,回车. 在输入框输入: terminal,回 ...

  2. AcWing:111. 畜栏预定(贪心 + 小根堆)

    有N头牛在畜栏中吃草. 每个畜栏在同一时间段只能提供给一头牛吃草,所以可能会需要多个畜栏. 给定N头牛和每头牛开始吃草的时间A以及结束吃草的时间B,每头牛在[A,B]这一时间段内都会一直吃草. 当两头 ...

  3. Latex的beamer幻灯片图形不编号的问题

    在beamer幻灯片中如果插入图形,一般不会显示图形编号,这是其默认模式,但我们可以通过设置给图形编号.解决办法是: 在导言区加上命令: \setbeamertemplate{caption}[num ...

  4. 怎样求控制器的增益系数k?

    步骤: 1.  \dot x =A*x + B*u is a state space model, with A and B are known. Now we want to locate the ...

  5. vue 项目安装

    安装stylus npm install stylus stylus-loader --save-dev

  6. [CSP-S模拟测试]:任务分配(最短路+贪心+DP)

    题目传送门(内部题149) 输入格式 每个测试点第一行为四个正整数$n,b,s,m$,含义如题目所述. 接下来$m$行,每行三个非负整数$u,v,l$,表示从点$u$到点$v$有一条权值为$l$的有向 ...

  7. 使用conda进行本地安装

    1. 由于安装源被墙转换为本地安装 例如要安装 boost-1.59版本,因为在默认源中没有,我们指定了特定源进行安装 conda install -c menpo dlib=boost-1.59 然 ...

  8. 8.1 HTML基础知识点

    8.1 HTML基础知识点 一.HTML是什么? Hyper Text Markup Language 超文本标记语言 的缩写 开发一个html文件,可以有很多方式 :比如Dreamweaver,HB ...

  9. C++入门经典-例9.2-重载函数模板,求出字符串的最小值

    1:整形数和实型数编译器可以直接进行比较,所以使用函数模板后也可以直接进行比较,但如果是字符指针指向的字符串该如何处理呢?这时可以通过重载函数模板来实现.通常字符串需要库函数来进行比较,通过重载函数模 ...

  10. [Java]算术表达式求值之三(中序表达式转二叉树方案 支持小数)

    Entry类 这个类对表达式的合法性进行了粗筛: package com.hy; import java.io.BufferedReader; import java.io.IOException; ...