[BZOJ2002][Hnoi2010]Bounce 弹飞绵羊
来源:互联网 发布:基于hadoop的数据挖掘 编辑:程序博客网 时间:2024/05/21 23:32
[Hnoi2010]Bounce 弹飞绵羊
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
Sample Output
2
3
Solution
不同于之前的LCT,这里要求维护一棵有根树,所以不能随便换根,一种方法是不换根link/cut,一种是给所有森林加一个公共根
Code
#include <bits/stdc++.h>using namespace std;#define rep(i, l, r) for (int i = (l); i <= (r); i++)typedef long long ll;typedef pair<int, int> PII;template<typename T> inline void read(T &x){ x = 0; T f = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); } while (isdigit(ch)) { x = x * 10 + ch - '0'; ch = getchar(); } x *= f;}const int N = 200100;struct Node{ int sz, rev_tag; Node *c[2], *fa; inline int d(){ if (fa->c[0] != this && fa->c[1] != this) return -1; return fa->c[1] == this; } inline void sc(Node *p, int d) { c[d] = p; p->fa = this; } inline void push_up(){ sz = c[0]->sz + c[1]->sz + 1; } inline void rev(){ swap(c[0], c[1]); rev_tag ^= 1; } void push_down();}pool[N<<1], *null=pool, *tail=pool+1, *loc[N];void Node :: push_down(){ if (this->d() != -1) fa->push_down(); if (rev_tag){ rep(i, 0, 1) if (c[i] != null) c[i]->rev(); rev_tag ^= 1; }}int n, m, k[N];inline void setnull(){ null->c[0] = null->c[1] = null->fa = null; null->sz = null->rev_tag = 0;}inline Node *newNode(){ tail->c[0] = tail->c[1] = tail->fa = null; tail->sz = 1; tail->rev_tag = 0; return tail++;}void rot(Node *x){ Node *y = x->fa; int d = x->d(); if (y->d() == -1) x->fa = y->fa; else y->fa->sc(x, y->d()); y->sc(x->c[!d], d); y->push_up(); x->sc(y, !d);}void splay(Node *x){ for (x->push_down(); x->d() != -1; ){ if (x->fa->d() == -1) rot(x); else x->d() == x->fa->d() ? (rot(x->fa), rot(x)) : (rot(x), rot(x)); } x->push_up();}void access(Node *x){ for (Node *t = null; x != null; t = x, x = x->fa) splay(x), x->c[1] = t, x->push_up();}void mkroot(Node *x){ access(x); splay(x); x->rev(); }void link(Node *x, Node *y){ mkroot(x); x->fa = y; }void cut(Node *x, Node *y){ mkroot(x); access(y); splay(y); y->c[0] = x->fa = null; y->push_up(); }int main(){ setnull(); read(n); rep(i, 1, n+1) loc[i] = newNode(); rep(i, 1, n){ read(k[i]); link(loc[i], loc[min(i+k[i], n+1)]); } read(m); for (; m; m--){ int opt, j, w; read(opt); read(j); j++; if (opt == 1){ mkroot(loc[j]); access(loc[n+1]); splay(loc[n+1]); printf("%d\n", loc[n+1]->sz-1); }else { read(w); cut(loc[j], loc[min(n+1, j+k[j])]); link(loc[j], loc[min(n+1, j+(k[j] = w))]); } } return 0;}
0 0
- [BZOJ2002][Hnoi2010]Bounce 弹飞绵羊 && LCT
- bzoj2002:[Hnoi2010]Bounce 弹飞绵羊
- [BZOJ2002][Hnoi2010]Bounce 弹飞绵羊
- 【HNOI2010】【BZOJ2002】Bounce 弹飞绵羊
- BZOJ2002: [Hnoi2010]Bounce 弹飞绵羊
- 【bzoj2002】 [Hnoi2010]Bounce 弹飞绵羊
- bzoj2002: [Hnoi2010]Bounce 弹飞绵羊
- [BZOJ2002] [Hnoi2010]Bounce 弹飞绵羊
- 【bzoj2002】[Hnoi2010]Bounce 弹飞绵羊
- [BZOJ2002][Hnoi2010]Bounce 弹飞绵羊
- 【bzoj2002】[Hnoi2010]Bounce 弹飞绵羊
- bzoj2002【HNOI2010】Bounce 弹飞绵羊
- bzoj2002 [Hnoi2010]Bounce 弹飞绵羊 (分块)
- bzoj2002: [Hnoi2010]Bounce 弹飞绵羊
- [bzoj2002] [Hnoi2010]Bounce 弹飞绵羊
- 【bzoj2002】【Hnoi2010】【Bounce】【弹飞绵羊】【分块】
- HNOI2010 bounce 弹飞绵羊 (BZOJ2002)
- 【Hnoi2010】Bzoj2002 Bounce & Codevs2333 弹飞绵羊
- 获取布局填充器(获取布局解析器)
- Google Gson 使用简介
- 进程和线程
- NeuralTalk2---自动产生图片的语句描述
- SQLite3 一列多行合并为一列一行
- [BZOJ2002][Hnoi2010]Bounce 弹飞绵羊
- 5.七个重点网络协议
- Android keyevent 对应的值
- 中国标准城市区域码
- Unity中的输入事件总结与数字电视遥控器键值映射
- 高精度模板
- 【多题合集】AC自动机练习,被HDU支配的恐惧
- 第三章 改进神经网络的学习方式(上)
- iOS7新特性 ViewController转场切换(二) 系统视图控制器容器的切换动画---push pop present dismis