CF 13E Holes

Holes

题意:现在有一排洞,每个洞有一个弹力,能弹到ai之后的洞,球会弹到这个排的外面,现在有2个操作,0 a b 将第a个洞的弹力设为b, 1 a 将球放入第a个洞,求输出进洞的次数 和 弹出这排洞进入的最后一个洞。

题解:分块暴力,对于每一个块,记录下这每一个点到下一个块的入口位置,和在这个块的最后到的点,还有就是进洞次数。然后每次修改的时候,暴力更新这个块的前半部分就好了。

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
 4 #define LL long long
 5 #define ULL unsigned LL
 6 #define fi first
 7 #define se second
 8 #define pb push_back
 9 #define lson l,m,rt<<1
10 #define rson m+1,r,rt<<1|1
11 #define max3(a,b,c) max(a,max(b,c))
12 #define min3(a,b,c) min(a,min(b,c))
13 #define _S(X) cout << x << ' ';
14 #define __S(x) cout << x << endl;
15 typedef pair<int,int> pll;
16 const int INF = 0x3f3f3f3f;
17 const LL mod =  (int)1e9+7;
18 const int N = 1e5 + 100;
19 int belong[N], l[N], r[N];
20 int to[N], tto[N], cnt[N], fin[N];
21 int n, m, tot, q, op, k, v;
22 void PushDown(int x){
23     int idx = belong[x];
24     for(int i = x; i >= l[idx]; i--){
25         if(to[i] > r[idx]) tto[i] = to[i], cnt[i] = 1, fin[i] = i;
26         else {
27             tto[i] = tto[to[i]];
28             cnt[i] = cnt[to[i]] + 1;
29             fin[i] = fin[to[i]];
30         }
31     }
32 }
33 void Build(){
34     m = sqrt(n);
35     tot = n/m;
36     if(n%m) tot++;
37     for(int i = 1; i <= n; i++){
38         cnt[i] = 0;
39         belong[i] = (i-1) / m + 1;
40     }
41     for(int i = 1; i <= tot; i++){
42         l[i] = (i-1)*m + 1;
43         r[i] = i*m;
44     }
45     r[tot] = n;
46     for(int i = 1; i <= tot; i++)
47         PushDown(r[i]);
48 }
49 void Query(int x){
50     int ret = 0, y = x, t;
51     while(x != n+1){
52         ret += cnt[x];
53         y = fin[x];
54         x = tto[x];
55     }
56     printf("%d %d\n", y, ret);
57 }
58 int main(){
59     scanf("%d%d", &n, &q);
60     for(int i = 1; i <= n; i++){
61         scanf("%d", &to[i]);
62         to[i] += i;
63         if(to[i] > n) to[i] = n+1;
64     }
65    Build();
66     while(q--){
67         scanf("%d", &op);
68         if(op == 0){
69             scanf("%d", &k);
70             scanf("%d", &to[k]);
71             to[k] += k;
72             if(to[k] > n) to[k] = n+1;
73             PushDown(k);
74         }
75         else {
76             scanf("%d", &k);
77             Query(k);
78         }
79     }
80     return 0;
81 }
CF 13E

 

posted @ 2018-05-31 16:55  Schenker  阅读(195)  评论(0编辑  收藏  举报