zoukankan      html  css  js  c++  java
  • UESTC 1324:卿学姐与公主(分块)

    http://acm.uestc.edu.cn/#/problem/show/1324

    题意:……

    思路:卿学姐的学习分块例题。

    分块是在线处理区间问题的类暴力算法,复杂度O(n*sqrt(n)),把给出的n个点的信息分成sqrt(n)个块,每个块有sqrt(n)个元素,然后去处理操作。

    从块的左边扫到块的右边复杂度最多是O(sqrt(n)),然后扫过所有的块复杂度最多是O(sqrt(n))。

    (画的好丑= =)

    这个图一个一个区间代表一个块。比如这里我们要处理[L,R]的问题,那么从L扫到属于L的块的右边界复杂度最多O(sqrt(n)),从不属于L的块扫到不属于R的块最多sqrt(n)个块,因此复杂度最多O(sqrt(n)),再从属于R的块的左边界扫到R,复杂度也是最多O(sqrt(n)),因此,总的复杂度是O(sqrt(n))。

    很美妙的处理啊。

     1 #include <cstdio>
     2 #include <cmath>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 #define N 100010
     7 typedef long long LL;
     8 
     9 int sz, num, l[N], r[N], belong[N], n;
    10 LL a[N], block[N];
    11 
    12 void Build() {
    13     sz = sqrt(n); // 每个块的大小
    14     num = n / sz; if(n % sz) num++; // 块的数量,如果n有剩余,那么要分多一个块
    15     for(int i = 1; i <= num; i++)
    16         l[i] = (i - 1) * sz + 1, r[i] = i * sz; // 每个块在数组的[l, r]区间,即块的管辖范围
    17     r[num] = n;
    18     for(int i = 1; i <= n; i++)
    19         belong[i] = (i - 1) / sz + 1; // 第i个元素属于第belong[i]个块
    20 }
    21 
    22 void Update(int id, int w) {
    23     a[id] += w;
    24     block[belong[id]] = max(block[belong[id]], a[id]);
    25 }
    26 
    27 LL Query(int L, int R) {
    28     LL ans = 0;
    29     if(belong[L] == belong[R]) // 如果属于同一个块,暴力扫,复杂度最大sqrt(n)
    30         for(int i = L; i <= R; i++) ans = max(ans, a[i]);
    31     else { // 如果不属于同一个块
    32         for(int i = L; i <= r[belong[L]]; i++) ans = max(ans, a[i]); // 暴力把左边扫到左边的块的右边界
    33         for(int i = belong[L] + 1; i <= belong[R] - 1; i++) ans = max(ans, block[i]); // 暴力扫不属于左边和右边的块
    34         for(int i = l[belong[R]]; i <= R; i++) ans = max(ans, a[i]); // 暴力从属于右边的快的左边界扫到右边
    35     }
    36     return ans;
    37 }
    38 
    39 int main() {
    40     int q;
    41     while(~scanf("%d%d", &n, &q)) {
    42         memset(block, 0, sizeof(block));
    43         memset(a, 0, sizeof(a));
    44         Build();
    45         while(q--) {
    46             int a, b, c;
    47             scanf("%d%d%d", &a, &b, &c);
    48             if(a == 1) Update(b, c);
    49             else printf("%lld
    ", Query(b, c));
    50         }
    51     }
    52     return 0;
    53 }
  • 相关阅读:
    (转载) mysql中,option是保留字段么?
    (转载)腾讯CMEM的PHP扩展
    (转载)一句简单命令重启nginx
    (转载)四种常见的 POST 提交数据方式
    (转载)完美解决PHP中文乱码问题
    (转载)file_get_contents("php://input")
    (转载)PHP 下 CURL 通过 POST 提交表单失败的原因之一与解决办法
    (转载)php array_merge 和 两数组相加区别
    Immutable-不变模式与不变类
    zookeeper 编程框架 curator
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6353786.html
Copyright © 2011-2022 走看看