bzoj 2002: [Hnoi2010]Bounce 弹飞绵羊
2015-06-03 20:36
381 查看
Description
某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞。绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞。为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数。Input
第一行包含一个整数n,表示地上有n个装置,装置的编号从0到n-1,接下来一行有n个正整数,依次为那n个装置的初始弹力系数。第三行有一个正整数m,接下来m行每行至少有两个数i、j,若i=1,你要输出从j出发被弹几次后被弹飞,若i=2则还会再输入一个正整数k,表示第j个弹力装置的系数被修改成k。对于20%的数据n,m<=10000,对于100%的数据n<=200000,m<=100000Output
对于每个i=1的情况,你都要输出一个需要的步数,占一行。Sample Input
41 2 1 1
3
1 1
2 1 1
1 1
Sample Output
23
第一棵LCT虽然只有access操作...
总之就是LCT乱搞啦..照着代码抄一遍感受感受大概可以懂..
#include<cstdio> using namespace std; struct tree { int l,r; int sz; int fa; bool rt; }tr[800001]; inline void pushup(int x) { tr[x].sz=tr[tr[x].l].sz+tr[tr[x].r].sz+1; } tree nx; inline void zig(int x) { tr[0]=nx; int t=tr[x].l; tr[x].l=tr[t].r; tr[tr[t].r].fa=x; tr[t].r=x; tr[t].fa=tr[x].fa; tr[x].fa=t; if(tr[x].rt) { tr[x].rt=false; tr[t].rt=true; } else { if(x==tr[tr[t].fa].l) tr[tr[t].fa].l=t; else tr[tr[t].fa].r=t; } pushup(x); } inline void zag(int x) { tr[0]=nx; int t=tr[x].r; tr[x].r=tr[t].l; tr[tr[t].l].fa=x; tr[t].l=x; tr[t].fa=tr[x].fa; tr[x].fa=t; if(tr[x].rt) { tr[x].rt=false; tr[t].rt=true; } else { if(x==tr[tr[t].fa].l) tr[tr[t].fa].l=t; else tr[tr[t].fa].r=t; } pushup(x); } inline void splay(int x) { while(!tr[x].rt) { int y=tr[x].fa,z=tr[y].fa; if(tr[y].rt) { if(x==tr[y].l) zig(y); else zag(y); } else if(y==tr[z].l) { if(x==tr[y].l){zig(z);zig(y);} else{zag(y);zig(z);} } else { if(x==tr[y].r){zag(z);zag(y);} else{zig(y);zag(z);} } } pushup(x); } inline void access(int x) { int y=0; while(x!=0) { splay(x); tr[tr[x].r].rt=true; tr[x].r=y; tr[y].rt=false; pushup(x); y=x; x=tr[x].fa; } } int a[200001]; int main() { int n; scanf("%d",&n); int i; for(i=1;i<=n;i++) scanf("%d",&a[i]); for(i=0;i<=n+1;i++) { tr[i].rt=true; tr[i].sz=1; if(i<=n) tr[i].fa=(i+a[i]>n)?n+1:i+a[i]; } tr[0].sz=0; int m; scanf("%d",&m); for(i=1;i<=m;i++) { int x,s,t; scanf("%d",&x); if(x==1) { scanf("%d",&s); s++; access(s); splay(s); printf("%d\n",tr[s].sz-1); } else { scanf("%d%d",&s,&t); s++; access(s); splay(s); tr[tr[s].l].fa=tr[s].fa; tr[tr[s].l].rt=true; tr[s].l=0; tr[s].fa=(s+t>n)?n+1:s+t; pushup(s); } } return 0; }
相关文章推荐
- 海马汽车经销商管理系统技术解析(十三)结算
- 如何在linux下检测内存泄漏
- 有关ROI的操作
- NFS服务搭建方案
- Linux定时任务Crontab详解
- PHP反射
- 黑马程序员_Java_集合总结
- 后缀树
- Android 本地化和国际化
- OC 基础知识遗漏点
- C++学习篇
- 应用 Valgrind 发现 Linux 程序的内存问题
- Balanced Binary Tree --Leetcode C++
- <a> href属性--记录八
- hdu 1394 Minimum Inversion Number 线段树 点更新
- 黑马程序员_Eclipse介绍及使用
- 黑马程序员_Java集合概述
- Shell 常用文本处理命令
- win7下配置OpenCV的Qt开发环境
- Valgrind简单用法