zoukankan      html  css  js  c++  java
  • 【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 }
  • 相关阅读:
    瓜子二手车直卖网面试经历
    189. Rotate Array
    183. Customers Who Never Order
    182. Duplicate Emails
    文本的样式
    字体font
    定位position
    float引起的高度塌陷问题
    盒子大小 轮廓阴影 圆角
    文档流 颜色单位
  • 原文地址:https://www.cnblogs.com/DrunBee/p/2660087.html
Copyright © 2011-2022 走看看