(我没看题解,写法可能有一点不同,但思路是一样的) 我用静态区间块长,像这样:
#include <bits/stdc++.h>
using namespace std;
constexpr int len = 128;
constexpr int maxn = 2e5 + 5;
constexpr int maxb = maxn / len + 1;
int n, q;
#define from(i) ((i)/len)
#define leftp(i) ((i)*len)
#define rightp(i) (leftp((i)+1)-1)
int step[maxn];
int a[maxn];
int pos[maxn];
void upd(int i, int x) {
int s = from(i), t = i + x;
step[i] = x;
if (t <= rightp(s)) a[i] = a[t] + 1, pos[i] = pos[t];
else a[i] = 1, pos[i] = t;
for (int k = i - 1, l = leftp(s), r = rightp(s); k >= l; --k) {
int t = k + step[k];
if (t <= r) {
a[k] = a[t] + 1, pos[k] = pos[t];
}
}
}
int query(int i) {
int cnt = 0;
while (i < n) {
cnt += a[i];
i = pos[i];
}
return cnt;
}
int main() {
ios::sync_with_stdio(false); cin.tie(0);
cin >> n;
for (int i = 0; i < n; ++i) {
cin >> step[i];
}
for (int i = 0; i < n; ++i) {
int r = min(rightp(from(i)), n - 1);
int cnt = 0, k = i;
do ++cnt, k += step[k];
while (k <= r);
a[i] = cnt, pos[i] = k;
}
cin >> q;
for (int t = 0; t < q; ++t) {
int op; cin >> op;
if (op == 1) {
int j; cin >> j;
cout << query(j) << '\n';
} else {
int j, k; cin >> j >> k;
upd(j, k);
}
}
return 0;
}
块长取255:
块长取107:
???
动态区间块长:
#include <bits/stdc++.h>
using namespace std;
int len;
constexpr int maxn = 2e5 + 5;
int n, q;
#define from(i) ((i)/len)
#define leftp(i) ((i)*len)
#define rightp(i) (leftp((i)+1)-1)
int step[maxn];
int a[maxn];
int pos[maxn];
void upd(int i, int x) {
int s = from(i), t = i + x;
step[i] = x;
if (t <= rightp(s)) a[i] = a[t] + 1, pos[i] = pos[t];
else a[i] = 1, pos[i] = t;
for (int l = leftp(s), r = rightp(s), k = r; k >= l; --k) {
int t = k + step[k];
if (t <= r) {
a[k] = a[t] + 1, pos[k] = pos[t];
} else {
a[k] = 1, pos[k] = t;
}
}
}
int query(int i) {
int cnt = 0;
while (i < n) {
cnt += a[i];
i = pos[i];
}
return cnt;
}
int main() {
ios::sync_with_stdio(false); cin.tie(0);
cin >> n; len = sqrt(n);
for (int i = 0; i < n; ++i) {
cin >> step[i];
}
for (int i = 0; i < n; ++i) {
int r = min(rightp(from(i)), n - 1);
int cnt = 0, k = i;
do ++cnt, k += step[k];
while (k <= r);
a[i] = cnt, pos[i] = k;
}
cin >> q;
for (int t = 0; t < q; ++t) {
int op; cin >> op;
if (op == 1) {
int j; cin >> j;
cout << query(j) << '\n';
} else {
int j, k; cin >> j >> k;
upd(j, k);
}
}
return 0;
}
所以???(大雾