分块求调
查看原帖
分块求调
530349
天空即为极限楼主2023/2/3 15:27
#include <bits/stdc++.h>
using namespace std;
int a[100005], pos[100005], R[505], L[505], n;

#define fi first
#define se second
pair <int, int> f[100005];
#define pii pair <int, int> 

void update (int x, int y) {
  int id = pos[x]; a[x] = y;
  for (int i = R[id]; i >= L[id]; i --)
    if (i + a[i] > R[i]) f[i] = {i + a[i], 1};
      else f[i] = {f[i + a[i]].fi, f[i + a[i]].se + 1};
}

int ask (int x) {
  int now = x, ans = 0;
  while (now <= n) {
    ans += f[now].se;
    now = f[now].fi;
  }
  return ans;
}

int main () {
  int num, siz, m; 
  
  cin >> n; siz = sqrt (n);
  
  num = n / siz + (n % siz != 0);
  
  for (int i = 1; i <= n; i ++) cin >> a[i];
  
  for (int i = 1; i <= n; i ++) 
    pos[i] = (i - 1) / siz + 1;
  
  for (int i = 1; i <= num; i ++) 
    R[i] = siz * i, L[i] = (i - 1) * siz + 1;
  
  R[num] = n;
  
  for (int i = num; i >= 1; i --) {
    for (int j = R[i]; j >= L[i]; j --) {
      if (j + a[j] > R[i]) f[j] = {j + a[j], 1};
      else f[j] = {f[j + a[j]].fi, f[j + a[j]].se + 1};
    }
  }
  
  cin >> m;
  
  while (m --) {
    int opt, x; cin >> opt >> x;
    if (opt == 1) cout << ask (x + 1) << "\n";
    else { int y; cin >> y; update (x + 1, y); }
  }
}

大红大紫

2023/2/3 15:27
加载中...