Title
Portal P3203 [HNOI2010] Bouncing Sheep
answer
F [ i ] F[i] F [ i ] represents fromiiThe number of bombs from the position i to the fly, then there is a recurrenceF [i] = F [i + ki] + 1 F[i]=F[i+k_i]+1F[i]=F[i+ki]+1 . Modify any positioniii capital possible oppositej (j <i) j (j <i)j ( j<The position of i ) has an impact, and there are two naive approaches:O (N) O(N)O ( N ) to modify,O (1) O(1)O ( 1 ) to query;O (1) O (1)O ( 1 ) to modify,O (N) O(N)O ( N ) to query. Need to balance the complexity of modification and query.
Consider blocking, nxt [i] nxt[i]n x t [ i ] Representative positioniii jumps out of the first position of the block,F [i] F[i]F [ i ] Representativeiii tonxt [i] nxt [i]n x t [ i ] The number of bombs. ThenO (N) O(\sqrt N)O (N) Violent reconstruction of the block where the modified position is located,O (N) O(\sqrt N)O (N) Query. Total time complexityO (MN) O(M\sqrt N)O ( MN)。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 200005, maxq = 1005;
int N, M, A[maxn];
int tot, L[maxq], R[maxq], id[maxn], nxt[maxn], F[maxn];
void change(int l, int x)
{
A[l] = x;
int p = id[l];
for (int i = R[p]; i >= L[p]; --i)
if (i + A[i] > R[p])
nxt[i] = i + A[i], F[i] = 1;
else
nxt[i] = nxt[i + A[i]], F[i] = F[i + A[i]] + 1;
}
int ask(int l)
{
int res = 0;
while (l <= N)
res += F[l], l = nxt[l];
return res;
}
int main()
{
scanf("%d", &N);
for (int i = 1; i <= N; ++i)
scanf("%d", A + i);
int w = sqrt(N);
for (int i = 1; i <= N; i += w)
L[++tot] = i, R[tot] = min(N, i + w - 1);
for (int i = 1; i <= tot; ++i)
for (int j = L[i]; j <= R[i]; ++j)
id[j] = i;
for (int i = N; i; --i)
if (i + A[i] > R[id[i]])
nxt[i] = i + A[i], F[i] = 1;
else
nxt[i] = nxt[i + A[i]], F[i] = F[i + A[i]] + 1;
scanf("%d", &M);
while (M--)
{
int i, j, k;
scanf("%d%d", &i, &j);
++j;
if (i == 1)
printf("%d\n", ask(j));
else
scanf("%d", &k), change(j, k);
}
return 0;
}