fork download
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. typedef long long ll;
  5. typedef pair<int, int> ii;
  6.  
  7. const int INF = 1e9;
  8. const ll LINF = 1e18;
  9.  
  10. const int N = 1e5 + 5;
  11. const int B = 316; // Kích thước 1 block
  12. const int K = 317; // Số block
  13.  
  14. int n, m;
  15. int a[N];
  16.  
  17. int id[N]; // id[i] là số hiệu của block quản lí i
  18. int l[K], r[K]; // l[id], r[id] là đầu mút trái nhất và phải nhất của block id
  19. int nxt[N]; // nxt[i] là ô đầu tiên của block tiếp theo mà i có thể nhảy đến
  20. int step[N]; // step[i] là số bước cần để từ ô i nhảy được đến ô nxt[i]
  21.  
  22. void build() {
  23. for (int i = 0; i < K; i++) l[i] = r[i] = -1;
  24.  
  25. for (int i = 1; i <= n; i++) {
  26. id[i] = i / B;
  27. if (l[id[i]] == -1) l[id[i]] = i;
  28. r[id[i]] = i;
  29. }
  30.  
  31. for (int i = n; i >= 1; i--) {
  32. if (i + a[i] > r[id[i]]) {
  33. step[i] = 1;
  34. nxt[i] = i + a[i];
  35. }
  36. else {
  37. step[i] = 1 + step[i + a[i]];
  38. nxt[i] = nxt[i + a[i]];
  39. }
  40. }
  41. }
  42.  
  43. int main() {
  44. ios::sync_with_stdio(0); cin.tie(0);
  45. cin >> n >> m;
  46. for (int i = 1; i <= n; i++) cin >> a[i];
  47.  
  48. build(); // O(n)
  49.  
  50. while (m--) {
  51. int type; cin >> type;
  52.  
  53. if (type == 0) {
  54. int pos, val;
  55. cin >> pos >> val;
  56. a[pos] = val;
  57. for (int i = pos; i >= l[id[pos]]; i--) { // O(B)
  58. if (i + a[i] > r[id[i]]) {
  59. step[i] = 1;
  60. nxt[i] = i + a[i];
  61. }
  62. else {
  63. step[i] = 1 + step[i + a[i]];
  64. nxt[i] = nxt[i + a[i]];
  65. }
  66. }
  67. }
  68. else {
  69. int s; cin >> s;
  70.  
  71. // Từ s ta sử dụng mảng nxt[] đã tính để nhảy đến block cuối cùng
  72. // Trong quá trình nhảy thì ta cũng cộng thêm số bước ở mỗi lần nhảy
  73. int ans = 0, last = -1;
  74. while (nxt[s] <= n) { // O(N / B)
  75. ans += step[s];
  76. s = nxt[s];
  77. }
  78.  
  79. // Khi đã đến block cuối cùng (block có chứa n)
  80. // thì ta sẽ nhảy chay cho đến khi vượt ra khỏi mảng
  81. // Trong quá trình nhảy thì cũng lưu lại ô trước đó đã đi qua
  82. while (s <= n) { // O(B)
  83. ++ans;
  84. last = s;
  85. s = s + a[s];
  86. }
  87.  
  88. cout << last << ' ' << ans << '\n';
  89. }
  90. }
  91. }
  92.  
Success #stdin #stdout 0.01s 5276KB
stdin
8 5
1 1 1 1 1 2 8 2
1 1
0 1 3
1 1
0 3 4
1 2
stdout
8 7
8 5
7 3