当前位置: 代码迷 >> 综合 >> BZOJ2002[Hnoi2010][Bounce 弹飞绵羊]
  详细解决方案

BZOJ2002[Hnoi2010][Bounce 弹飞绵羊]

热度:86   发布时间:2023-11-06 09:28:36.0

solution:对于每个点,我们记录两个值:1.它要跳几次才能跳出它所在的块。2.它跳出块以后跳到哪里。这样,我们就可以o(sqr(n))地修改和查询了

#include <cmath>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;#define N 200005
#define ll long long
int a[N], cn[N], cp[N], bl[N];
int cnt , blk, n, m;inline int Read () {int x = 0 , f = 1 ;char ch = getchar () ;while ( ! isdigit ( ch ) ) {if ( ch == '-' ) f = -1 ;ch = getchar () ;}while ( isdigit ( ch ) ) {x = x * 10 + ch - '0' ;ch = getchar () ;}return x * f ;
}
int calc( int x ){int tmp = 0;for ( ;; ){tmp += cn[x];if ( !cp[x] ) break;x = cp[x];}return tmp;
}int main(){n = read();for ( int i = 1; i <= n; i++) a[i] = read();blk = sqrt(n);if ( n % blk ) cnt = n / blk + 1 ;else cnt = n / blk;for ( int i = 1; i <= n; i++) bl[i] = (i-1)/blk + 1;for ( int i = n; i >= 1; i-- ){if ( i + a[i] > n ) cn[i] = 1;else if ( bl[i] == bl[i+a[i]] ) cn[i] = cn[i+a[i]]+1, cp[i] = cp[i+a[i]];else cn[i] = 1, cp[i] = i+a[i];}m = read();while ( m-- ){int x, y, z;x = Read () , y = Read () , ++ y ;if ( x == 1 ){printf( "%d\n", calc(y));}else {z = read();a[y] = z;for ( int i = y; i >= (bl[y]-1)*blk +1; i-- ){if ( bl[i] == bl[i+a[i]] )cn[i] = cn[i+a[i]]+1, cp[i] = cp[i+a[i]];else cn[i] = 1, cp[i] = i+a[i];}}}return 0;
}