【CodeForces】13E Holes

题意:

有n个洞,编号1~n,每个洞有一个power,若有球掉入第i个洞,会被弹到第i+power[i]个洞。

两种操作:

1,球掉入第i个洞后,问弹出n个洞前最后掉入的洞的编号,以及弹的次数。

2,修改第i个洞的power值。

 

很裸的动态树。与这题本质上是相同的:【HYSBZ】1036 树的统计Count

但是,通过分块暴力,可以做到O(n*sqrt(n))。

很显然,将1~n分成sqrt(n)块。

一个很直接的想法,把a块的最后一个直接指向b块的最后一个(a!=b),这样暴力非完整的块,其他块O(1)得到。

但是,可以有更简单的写法,把相同块中每个洞都指向会到达的最后一个洞,并统计其中跳过多少个。

查询就暴力统计下,修改就暴力修改一整块,复杂度都是O(sqrt(n))。

 1 #include<cstdio>

 2 #include<cmath>

 3 #include<algorithm>

 4 #define EPS 1e-9

 5 #define MAXN 100010

 6 using namespace std;

 7 int n, block;

 8 int power[MAXN], next[MAXN], end[MAXN], cnt[MAXN];

 9 void Update(int x, int y) {

10     if (y > n) {

11         end[x] = x;

12         cnt[x] = 1;

13         next[x] = y;

14     } else {

15         end[x] = end[y];

16         if (x / block == y / block) {

17             next[x] = next[y];

18             cnt[x] = cnt[y] + 1;

19         } else {

20             next[x] = y;

21             cnt[x] = 1;

22         }

23     }

24 }

25 void Query(int a, int &x, int &y) {

26     for (x = 0;; a = next[a]) {

27         x += cnt[a];

28         if (next[a] > n) {

29             y = end[a];

30             break;

31         }

32     }

33 }

34 int main() {

35     int i, q;

36     int cmd, a, b, x, y;

37     while (~scanf("%d%d", &n, &q)) {

38         block = (int) (ceil(sqrt((double) n)) + EPS);

39         for (i = 1; i <= n; i++)

40             scanf("%d", &power[i]);

41         for (i = n; i; i--)

42             Update(i, i + power[i]);

43         while (q--) {

44             scanf("%d%d", &cmd, &a);

45             if (cmd) {

46                 Query(a, x, y);

47                 printf("%d %d\n", y, x);

48             } else {

49                 scanf("%d", &b);

50                 power[a] = b;

51                 x = a / block * block;

52                 y = x + block;

53                 x = max(x, 1);

54                 y = min(y, n);

55                 for (i = y - 1; i >= x; i--)

56                     Update(i, i + power[i]);

57             }

58         }

59     }

60     return 0;

61 }

你可能感兴趣的:(codeforces)