【分块】【Luogu P3203】弹飞绵羊

链接

Luogu P3203

题目描述

在这里插入图片描述

思路

分块,在一个块内就直接处理,修改也是只改一个块的就可以了

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long

using namespace std;

ll n, m, ans;
ll a[200005], step[200005], to[200005];
ll l[5005], r[5005], belong[200005];

ll read()
{
    
    
	ll re = 0;
	char ch = getchar();
	while(ch < '0' || ch > '9') ch = getchar();
	while('0' <= ch && ch <= '9') {
    
    
		re = re * 10 + ch - 48;
		ch = getchar();
	}
	return re;
}

int main()
{
    
    
//	freopen("P3203_1.in","r",stdin);
	n = read();
	ll size = sqrt(n);
	ll num = n / size;
	if(n % size != 0) num++;
	for(int i = 1; i <= n; ++i)
		a[i] = read();
	for(int i = 1; i <= num; ++i)
		l[i] = r[i - 1] + 1, r[i] = l[i] + size - 1;
	r[num] = n;
	for(int j = 1, i = 1; i <= num; ++j)
	{
    
    
		belong[j] = i;
		if(j == r[i]) ++i;
	}
	for(int i = n; i >= 1; --i)//从后往前去修改
	{
    
    
		to[i] = i + a[i];
		if(to[i] > r[belong[i]]) step[i] = 1;
		else step[i] = step[to[i]] + 1, to[i] = to[to[i]];
	}
	m = read();
	for(int i = 1; i <= m; ++i)
	{
    
    
		int type = read();
		if(type == 1) {
    
    
			ans = 0; 
			int x = read(); x++;
			while(x <= n) ans += step[x], x = to[x];
			printf("%lld\n", ans);
		}
		else {
    
    
			int x = read();  
			ll y = read();
			x++;
			a[x] = y;
			for(int i = r[belong[x]]; i >= l[belong[x]]; --i)
			{
    
    
				to[i] = i + a[i];
				if(to[i] > r[belong[i]]) step[i] = 1;
				else step[i] = step[to[i]] + 1, to[i] = to[to[i]];
			}
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/LTH060226/article/details/119840319
今日推荐