[Link-Cut-Tree][BZOJ2002]弹飞绵羊
题面
Description
某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿着一条直线摆上\(n\)个装置,每个装置设定初始弹力系数\(k_i\),当绵羊达到第\(i\)个装置时,它会往前弹\(k_i\)步,达到第\(i+k_i\)个装置,若不存在第\(i+k_i\)个装置,则绵羊被弹飞。绵羊想知道当它从第\(i\)个装置起步时,被弹几次后会被弹飞。为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数。
Input
第一行包含一个整数\(n\),表示地上有\(n\)个装置,装置的编号从\(0\)到\(n-1\)。
接下来一行有\(n\)个正整数,依次为那\(n\)个装置的初始弹力系数。
第三行有一个正整数\(m\)。
接下来\(m\)行每行至少有两个数\(i,j\),若\(i=1\),你要输出从\(j\)出发被弹几次后被弹飞,若\(i=2\)则还会再输入一个正整数\(k\),表示第\(j\)个弹力装置的系数被修改成\(k\)。
Output
对于每个\(i=1\)的情况,你都要输出一个需要的步数,占一行。
Sample Input
4
1 2 1 1
3
1 1
2 1 1
1 1
Sample Output
2
3
Hint
对于20%的数据\(n,m\le 10000\);
对于100%的数据\(n\le 200000,m\le 100000\);
1.如何建树?
- 若从这个点\(x\)会被弹飞,连边\((x,n+1)\)
- 若从这个点\(x\)不会被弹飞,连边\((x,x+k_x)\)
根为\(\textbf{n+1}\)
以样例做例子:
2.如何询问?
为蛤哈?
由于splay是按深度关键字排序,所以根的左子树的大小就是要被弹几次了呀。
3.如何修改?
把原来的边删了在连新的不就完了吗……
代码
#include<iostream>
#include<cstdio>
using namespace std;
int ch[200002][2],fa[200002],siz[200002],num[200002],lazr[200002],cnt,n,q;
inline unsigned rd(){
unsigned re=0;
char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9'){
re=re*10+ch-'0';
ch=getchar();
}
return re;
}
inline bool isroot(int bt){return ch[fa[bt]][0]!=bt&&ch[fa[bt]][1]!=bt;}
inline int drct(int bt){return ch[fa[bt]][1]==bt;}
inline void pushup(int bt){siz[bt]=siz[ch[bt][0]]+siz[ch[bt][1]]+1;}
inline void reverse(int bt){swap(ch[bt][0],ch[bt][1]);lazr[bt]^=1;}
inline void pd(int bt){
if(lazr[bt]){
if(ch[bt][0])reverse(ch[bt][0]);
if(ch[bt][1])reverse(ch[bt][1]);
lazr[bt]=0;
}
}
inline void pushdown(int u){
if(!isroot(u))pushdown(fa[u]);
pd(u);
}
inline void rotate(int u){
int f=fa[u],g=fa[f],c=drct(u);
if(!isroot(f))ch[g][drct(f)]=u;
fa[u]=g;
ch[f][c]=ch[u][c^1];
if(ch[f][c])fa[ch[f][c]]=f;
ch[u][c^1]=f;
fa[f]=u;
pushup(f);
pushup(u);
}
void splay(int u){
pushdown(u);
while(!isroot(u)){
if(!isroot(fa[u]))rotate(drct(fa[u])==drct(u)?fa[u]:u);
rotate(u);
}
}
void access(int u){
for(int v=0;u;v=u,u=fa[u]){
splay(u);
ch[u][1]=v;
pushup(u);
}
}
void makeroot(int u){
access(u);
splay(u);
reverse(u);
}
void link(int a,int b){
makeroot(a);
fa[a]=b;
}
void cut(int a,int b){
makeroot(a);
access(b);
splay(b);
ch[b][0]=0;
fa[a]=0;
pushup(b);
}
int main(){
n=rd();
for(int i=1;i<=n;i++){
num[i]=rd();
siz[i]=1;
}
for(int i=1;i<=n;i++){
if(i+num[i]<=n)fa[i]=i+num[i];
else fa[i]=n+1;
}
q=rd();
for(int i=1;i<=q;i++){
int opt=rd(),x=rd()+1;
if(opt==1){
makeroot(n+1);
access(x);
splay(x);
printf("%d\n",siz[ch[x][0]]);
}else{
int y=rd();
if(x+num[x]<=n)cut(x,x+num[x]);
else cut(x,n+1);
num[x]=y;
if(x+num[x]<=n)link(x,x+num[x]);
else link(x,n+1);
}
}
}
[Link-Cut-Tree][BZOJ2002]弹飞绵羊的更多相关文章
- BZOJ-2002 弹飞绵羊 Link-Cut-Tree (分块)
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 6801 Solved: 3573 [Submi ...
- bzoj2002 弹飞绵羊
Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置 ...
- bzoj2002 弹飞绵羊 lct版
这道题就是维护一个有根的lct 一开始建树全部建虚边 求多少次弹出就是求他到根的距离(根为n+1) 这里有个小技巧 将n+1作为根而没有虚根操作起来会比较方便 #include<cstdio&g ...
- BZOJ2002弹飞绵羊
动态树LCT模板题 #include<cstdio> #include<cctype> #include<algorithm> using namespace st ...
- bzoj2002 弹飞绵羊 分块
这道题是分块的初尝试 讲给定的区间n进行分块处理 这个每次修改的复杂的只有logn 很方便 代码是学黄学长的 http://hzwer.com/3505.html 当然里面还是有一定我自己的想法在里面 ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 (动态树LCT)
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 2843 Solved: 1519[Submi ...
- [BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree)
[BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree) 题面 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一 ...
- 【BZOJ 2002】【Hnoi 2010】弹飞绵羊 分块||Link Cut Tree 两种方法
ShallWe,Yveh,hmy,DaD3zZ,四人吃冰糕从SLYZ超市出来后在马路上一字排开,,,吃完后发现冰糕棍上写着:“向狮子座表白:愿做你的小绵羊”,,, 好吧在这道题里我们要弹飞绵羊,有分块 ...
- 【BZOJ2002】弹飞绵羊(Link-Cut Tree)
[BZOJ2002]弹飞绵羊(Link-Cut Tree) 题面 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lost ...
随机推荐
- BZOJ4503: 两个串(bitset字符串匹配)
题意 题目链接 Sol Orz xudyh F个毛T啊..直接bitset一波就赢了啊...(虽然复杂度很假) 就是记录匹配串中每个元素出现的位置,将第\(i\)个位置的bitset右移\(i\)位后 ...
- pc端的企业网站(IT修真院test8)详解1-4
今天完成的事情:(1,伪元素:before,:after的使用.2.table的使用(collapse的使用)3rgba的高级运用) 今天我主要完成test8-3的页面. header和footer都 ...
- Angular JS + Express JS入门搭建网站
3月份开始,接到了新的任务,跟UI开发有关,用的是Angular JS,Express JS等技术.于是周末顺便学习下新技术. 组里产品UI架构如下: 其中前端,主要使用Angular JS框架,另外 ...
- Struts2_HelloWorld1
打开 eclipse,新建 web 项目. 因为可能需要 jstl 表达式,所以添加 jstl需要的jar包. 下载链接:http://pan.baidu.com/s/1hr6mBI0 将jar拷贝至 ...
- [垂直化搜索引擎]lucene简介及使用
摘自:大型分布式网站架构-设计与实践
- 洛谷 P3905 道路重建
题目描述 从前,在一个王国中,在n个城市间有m条道路连接,而且任意两个城市之间至多有一条道路直接相连.在经过一次严重的战争之后,有d条道路被破坏了.国王想要修复国家的道路系统,现在有两个重要城市A和B ...
- 数据结构与算法分析java——线性表2(ArrarList )
ArrayList ArrayList 是一个数组队列,相当于 动态数组.与Java中的数组相比,它的容量能动态增长.它继承于AbstractList,实现了List, RandomAccess, C ...
- 257. Binary Tree Paths (dfs recurive & stack)
Given a binary tree, return all root-to-leaf paths. Note: A leaf is a node with no children. Example ...
- Socket的基本使用步骤
Socket的基本使用步骤 一.使用Socket,首先需要导入这几个系统头文件 #import <sys/socket.h> #import <netinet/in.h> #i ...
- MySQL锁小结
锁的作用:避免并发请求时对同一个数据对象同时修改,导致数据不一致. 怎么加锁: 1.事务T1在对某个数据对象R1操作之前,先向系统发出请求,对其加锁L1. 2.之后,事务T1对该数据对象R1有了相 ...