$description$ :
还是看题面, link
$solution$ :
- $1.$ 这是一道很显然的 $LCT$ 模板题
- $2.$ 由于我是比较懒的人 , 所以就用分块过掉的。
显然对于分块就不多解释了,这里分的块的块长为 $\sqrt n$ 。
我们设这么几个数组。
- $nxt_i$ 表示到达第 $i$ 个地方,并且根据当前地方的劲度系数,可以调到 $nxt_i$ 这个位置。
- $block_i$ 表示 $i$ 属于哪一个块。
对于修改的时候,我们由于是到达最后面的时候弹飞,所以我们从后往前逆向去推导 $nxt_i$
代码很好理解:
/*
By : Zmonarch
知识点:
提交网址 : https://www.acwing.com/problem/content/2168/
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <cstring>
#include <cmath>
#define int long long
#define inf 2147483647
#define qwq register
const int kmaxn = 1e6 + 10 ;
const int kmod = 998244353 ;
namespace Base
{
inline int Min(int a , int b) {return a < b ? a : b;}
inline int Max(int a , int b) {return a < b ? b : a;}
inline int Abs(int a) {return a < 0 ? - a : a;} ;
inline int Gcd(int a , int b) {return !b ? a : Gcd(b , a %b);}
}
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 n , m , len ;
int a[kmaxn] , block[kmaxn] , ans[kmaxn] , nxt[kmaxn];
int query(int u)
{
int ret = 0 ;
while(u)
{
ret += ans[u] ;
u = nxt[u] ;
}
return ret ;
}
void modify(int u , int k) // 修改的也就是暴力修改了,但是只是会对后面产生一定的影响
{
a[u] = k ;
for(qwq int i = u ; i && block[i] == block[u] ; i--)
{
if(i + a[i] > n) ans[i] = 1 , nxt[i] = 0 ; // 当前的可以弹飞
else if(block[i] == block[i + a[i]]) ans[i] = ans[i + a[i]] + 1 , nxt[i] = nxt[i + a[i]] ;
else ans[i] = 1 , nxt[i] = i + a[i] ;
}
}
signed main()
{
n = read() ; len = sqrt(n) ;
for(qwq int i = 1 ; i <= n ; i++) a[i] = read() , block[i] = i / len ;
for(qwq int i = n ; i >= 1 ; i--) //从后向前处理一下块来寻找
{
if(i + a[i] > n) ans[i] = 1 , nxt[i] = 0 ; // 当前的可以弹飞
else if(block[i] == block[i + a[i]]) ans[i] = ans[i + a[i]] + 1 , nxt[i] = nxt[i + a[i]] ;
else ans[i] = 1 , nxt[i] = i + a[i] ;
}
m = read() ;
for(qwq int i = 1 ; i <= m ; i++)
{
int opt = read() , u = read() + 1 ;
if(opt == 1 ) printf("%lld\n" , query(u)) ;
else modify(u , read()) ;
}
return 0 ;
}