[BZOJ2002] [Luo Gu P3203] [Hnoi2010] Bounce Danfei sheep (LCT maintenance chain length)

luogu Portal

2002: [Hnoi2010] Bounce Danfei sheep

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 16082  Solved: 8241
[Submit][Status][Discuss]

Description

One day, Lostmonkey invented a super-elastic device, in order to show off in front of his friend's sheep, he was invited to play a game with little sheep. A game start, Lostmonkey put on the ground along a line of n devices, each device sets the initial elastic coefficient ki, when sheep reaches an i-th unit, it will play the next step ki, ki to reach the i th + means, if the presence of the i + ki th device, sheep Danfei. Sheep want to know when it is starting from the i-th unit, after a few shells will Danfei. To make the game more interesting, Lostmonkey can modify the elasticity coefficient of an elastic device, any time elasticity coefficients are positive integers.

Input

The first row contains an integer n, there are n represents the ground means that the device was from 0 to n-1, the next row has n positive integer, followed by an initial elastic coefficient means that the n. The third row has a positive integer m, the next m lines each having at least two numbers i, j, if i = 1, j outputted from you several times after starting the playing Danfei, i = 2 if you also will enter a positive integer k, it denotes the j-th coefficient of the resilient means is modified to k. 20% to the data n, m <= 10000, a 100% data for n <= 200000, m <= 100000

Output

For each case i = 1, you have to export a number of steps required, per line.

Sample Input

4
1 2 1 1
3
1 1
2 1 1
1 1

Sample Output

2
3

HINT

Source

Solution

  We press the number 1-n Ha, no title is numbered starting from zero, because in this node 0 konjac written inside the LCT is ambiguous (fog), I'd use it to party. . .

  For each i, if k + k [i] <= n, then there is an edge considered i-> k + k [i] , or as the presence of side i-> virtual node n + 1. Then you will find that each node has one and only one out side, O, what do you think? Within the tree! However, the node n + 1 side so it was not an ordinary tree is a tree (LCT or how to use it).

  Then the answer to the query x is x n + 1 of the chain length, this fact will seek out easily, only need to maintain sz, then split it and x n + 1, the answer is at this time the root sz value minus 1.

  As for modification operations, is cut a little longer link it Well.

  There is, I can not BZOJ the casual use cout, and this constant Intuit also big. . .

Code

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
inline int read(){
    int x=0,w=0;char ch=0;
    while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    return w?-x:x;
}
int sz[N],f[N],c[N][2];
bool rv[N];
#define lc c[x][0]
#define rc c[x][1]
inline bool nrt(int x){return c[f[x]][0]==x||c[f[x]][1]==x;}
inline void pushup(int x){sz[x]=sz[lc]+sz[rc]+1;}
inline void rev(int x){lc^=rc^=lc^=rc;rv[x]^=1;}
inline void pushdown(int x){if(rv[x]) rev(lc),rev(rc),rv[x]=0;}
inline int get(int x){return c[f[x]][1]==x;}
inline void link(int x,int y,int d){c[x][d]=y,f[y]=x;}
void rotate(int x){
    int y=f[x],z=f[y],d=get(x);
    if(nrt(y)) c[z][get(y)]=x;f[x]=z;
    link(y,c[x][d^1],d);
    link(x,y,d^1);
    pushup(y),pushup(x);
}
int st[N],tp;
void splay(int x){
    int t=x;
    st[tp=1]=t;
    while(nrt(t)) st[++tp]=t=f[t];
    while(tp) pushdown(st[tp--]);
    for(;nrt(x);rotate(x))
        if(nrt(f[x])) get(x)^get(f[x])?rotate(x):rotate(f[x]);
}
void access(int x){
    for(int y=0;x;x=f[y=x])
        splay(x),c[x][1]=y,pushup(x);
}
void makert(int x){access(x),splay(x),rev(x);}
int findrt(int x){
    access(x),splay(x);
    while(lc) pushdown(x),x=lc;
    splay(x);return x;
}
void link(int x,int y){
    makert(x);if(findrt(y)^x) f[x]=y;
}
void cut(int x,int y){
    makert(x);
    if(findrt(y)==x&&f[y]==x&&!c[y][0]) f[y]=c[x][1]=0,pushup(x);
}
void split(int x,int y){
    makert(x),access(y),splay(y);
}
int n,m,k[N];
#define to(x) min(x+k[x],n+1)
int main(){
    n=read();
    for(int i=1;i<=n;++i) k[i]=read(),link(i,to(i));
    m=read();
    while(m--){
        int x=read(),y=read()+1;
        if(x&1){
            split(y,n+1);
            printf("%d\n",sz[n+1]-1);
        }
        else{
            cut(y,to(y));
            k[y]=read();
            link(y,to(y));  
        }
    }
    return 0;
}
BZOJ2002

 

  

Guess you like

Origin www.cnblogs.com/gosick/p/11256790.html