bzoj 2002: [Hnoi2010]Bounce 弹飞绵羊 lct模板
来源:互联网 发布:软件研制方案模板 编辑:程序博客网 时间:2024/04/19 23:13
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<=100000
Output
对于每个i=1的情况,你都要输出一个需要的步数,占一行。
Sample Input
4
1 2 1 1
3
1 1
2 1 1
1 1
1 2 1 1
3
1 1
2 1 1
1 1
Sample Output
2
3
3
分析:很水的lct模板~~
先建成一棵树,每次查询的时候把x转到根节点,结果就是x右子数的节点数量。
修改的时候就直接把x与fa的边断开然后连到另一个点上就好了。
还有这题还可以用分块做,但笔者太懒,就不写啦~~
代码:
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<stack>#define N 200005using namespace std;int n,next[N];struct tree{int fa,size,l,r,rev;}t[N];stack <int> q;void updata(int x){t[x].size=t[t[x].l].size+t[t[x].r].size+1;}void rttl(int x){int y=t[x].r;t[x].r=t[y].l;t[t[y].l].fa=x;if (x==t[t[x].fa].l) t[t[x].fa].l=y;else if (x==t[t[x].fa].r) t[t[x].fa].r=y;t[y].fa=t[x].fa;t[y].l=x;t[x].fa=y;updata(x);updata(y);}void rttr(int x){int y=t[x].l;t[x].l=t[y].r;t[t[y].r].fa=x;if (x==t[t[x].fa].l) t[t[x].fa].l=y;else if (x==t[t[x].fa].r) t[t[x].fa].r=y;t[y].fa=t[x].fa;t[y].r=x;t[x].fa=y;updata(x);updata(y);}bool isroot(int x){if (x!=t[t[x].fa].l&&x!=t[t[x].fa].r||!t[x].fa) return 1;return 0;}void pushdown(int x){if (t[x].rev){swap(t[x].l,t[x].r);if (t[x].l) t[t[x].l].rev^=1;if (t[x].r) t[t[x].r].rev^=1;t[x].rev^=1;}}void remove(int x){int y=x;while (1){q.push(y);if (isroot(y)) break;y=t[y].fa;}while (!q.empty()){int y=q.top();q.pop();pushdown(y);}}void splay(int x){remove(x);while (!isroot(x)){int p=t[x].fa,g=t[p].fa;if (isroot(p)){if (x==t[p].l) rttr(p);else rttl(p);break;}if (x==t[p].l){if (p==t[g].l){rttr(g);rttr(p);}else{rttr(p);rttl(g);}}else{if (p==t[g].r){rttl(g);rttl(p);}else{rttl(p);rttr(g);}}}}void access(int x){int y=0;while (x){splay(x);t[x].r=y;y=x;x=t[x].fa;}}void movetoroot(int x){access(x);splay(x);t[x].rev^=1;}void cut(int x,int y){movetoroot(x);access(y);splay(y);t[y].l=0;t[x].fa=0;}void link(int x,int y){movetoroot(x);access(y);t[y].r=x;t[x].fa=y;splay(x);}int findroot(int x){access(x);splay(x);while (t[x].l) x=t[x].l;return x;}int main(){scanf("%d",&n);for (int i=1;i<=n;i++){int k;scanf("%d",&k);t[i].fa=min(i+k,n+1);t[i].size=1;next[i]=t[i].fa;}t[n+1].size=1;int m;scanf("%d",&m);for (int i=1;i<=m;i++){int x;scanf("%d",&x);if (x==1){movetoroot(n+1);int y;scanf("%d",&y);y++;access(y);splay(y);printf("%d\n",t[t[y].l].size);}else{int y,z;scanf("%d%d",&y,&z);y++;int t=min(n+1,y+z);cut(y,next[y]);link(y,t);next[y]=t;}}return 0;}
0 0
- bzoj 2002: [Hnoi2010]Bounce 弹飞绵羊 lct模板
- BZOJ 2002 [Hnoi2010]Bounce 弹飞绵羊 (LCT)
- 【BZOJ】2002 [Hnoi2010]Bounce 弹飞绵羊 LCT入门题
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 LCT
- BZOJ 2002([Hnoi2010]Bounce 弹飞绵羊-LCT)
- BZOJ 2002 [Hnoi2010]Bounce 弹飞绵羊 LCT
- bzoj 2002: [Hnoi2010]Bounce 弹飞绵羊 (LCT)
- 【LCT】BZOJ 2002 [Hnoi2010]Bounce 弹飞绵羊
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 LCT
- 【BZOJ 2002】 [Hnoi2010]Bounce 弹飞绵羊 LCT
- [BZOJ 2002][Hnoi2010]Bounce 弹飞绵羊:分块|LCT
- BZOJ 2002 [Hnoi2010]Bounce 弹飞绵羊 LCT
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊(LCT)
- [LCT]BZOJ 2002——[Hnoi2010]Bounce 弹飞绵羊
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 LCT
- bzoj 2002 [Hnoi2010]Bounce 弹飞绵羊 LCT
- bzoj 2002: [Hnoi2010]Bounce 弹飞绵羊 LCT
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊
- 如何使用Linux匿名上网-四大法宝
- java的字符流简单介绍
- ab 模拟测试秒杀存在的问题
- Android自定义View: 如何实现类钟摆的动画效果?
- HDU:Counting Sheep
- bzoj 2002: [Hnoi2010]Bounce 弹飞绵羊 lct模板
- Leetcode - Tree - 106. Construct Binary Tree from Inorder and Postorder Traversal(根据中序遍历和后序遍历重构二叉树)
- RasInvokeEapUI
- Java-LeetCode-TwoSum
- 显式事务、隐式事务、分布式隐式事务、分布式显式事务 定义以及事例
- Web端&移动端测试的区别
- java数组详解
- CCF模拟题4-有趣的数 未知能否ac
- 获取当前进程Cpu使用率并自动导出到图表py脚本