BZOJ2002 HNOI2010 弹飞绵羊Bounce
Description
某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞。绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞。为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数。
Input
第一行包含一个整数n,表示地上有n个装置,装置的编号从0到n-1,接下来一行有n个正整数,依次为那n个装置的初始弹力系数。第三行有一个正整数m,接下来m行每行至少有两个数i、j,若i=1,你要输出从j出发被弹几次后被弹飞,若i=2则还会再输入一个正整数k,表示第j个弹力装置的系数被修改成k。对于20%的数据n,m<=10000,对于100%的数据n<=200000,m<=100000
Output
对于每个i=1的情况,你都要输出一个需要的步数,占一行。
Sample Input
4
1 2 1 1
3
1 1
2 1 1
1 1
Sample Output
2
3
最喜欢的题目......
不会LCT,分块做的;
对于每一个装置,维护几个值:跳出所在块所需步数及相应的落点;
预处理:从后向前维护;
查询:模拟一边就行;
修改:从修改位置向前直到所在块的左端点全都暴力改一遍;
代码:
1 //弹飞绵羊Bounce__HNOI 2010
2 #include<iostream>
3 #include<cstdio>
4 #include<cmath>
5 using namespace std;
6
7 inline void Read(int&);
8 const int maxn = 2e5 + 5;
9 int n, m, q;
10 int arr[maxn];
11 int blo[maxn], step[maxn], fall[maxn];
12 inline int Bounce(int);
13
14 int main()
15 {
16 Read(n);
17 m=sqrt(n);
18 for (int i = 1; i <= n; i++)
19 {
20 Read(arr[i]);
21 blo[i] = (i - 1) / m + 1;
22 }
23 for (int i = n; i > 0; i--)//预处理
24 {
25 if (i + arr[i] > n)
26 step[i] = 1;
27 else if (blo[i] == blo[i + arr[i]])
28 step[i] = step[i + arr[i]] + 1,
29 fall[i] = fall[i + arr[i]];
30 else
31 step[i] = 1, fall[i] = i + arr[i];
32 }
33 Read(q);
34 while(q--)
35 {
36 int ord, pos, v;
37 Read(ord), Read(pos);
38 pos++;
39 if (ord == 1)
40 printf("%d\n", Bounce(pos));//查询
41 else
42 {
43 Read(v);
44 arr[pos] = v;
45 int end = (blo[pos] - 1)*m + 1;
46 for (int i = pos; i >= end; i--)//修改
47 {
48 if (blo[i] == blo[i + arr[i]])
49 step[i] = step[i + arr[i]] + 1,
50 fall[i] = fall[i + arr[i]];
51 else step[i] = 1, fall[i] = i + arr[i];
52 }
53 }
54 }
55 return 0;
56 }
57
58 inline int Bounce(int pos)//查询的函数
59 {
60 int ans=0;
61 while (pos)
62 {
63 ans += step[pos];
64 pos = fall[pos];
65 }
66 return ans;
67 }
68
69 inline void Read(int &x)
70 {
71 x=0;
72 bool f=0;
73 char c=getchar();
74 while (c<'0' || c>'9')
75 {
76 f = (c == '-');
77 c = getchar();
78 }
79 while (c >= '0'&&c <= '9')
80 {
81 x = x * 10 + c - '0';
82 c = getchar();
83 }
84 if (f) x = -x;
85 return;
86 }