zoukankan      html  css  js  c++  java
  • 【学习心得】分块

    介绍

    分块是信息学中经常用到的一个思想。主要是通过将整个序列分割成根号个块来保证复杂度。分块可以对询问进行预处理,修改或查询时,主要就是靠完整的块打标记或直接查,不完整的块暴力改或暴力查。这样每个块中的操作的复杂度不会超过sqrt(n)。
    对于一些复杂的树形数据结构,在考场上有可能会紧张写不出来,这时候使用分块就是一个很好的选择,此时分块的代码复杂度与分数的性价比是很高的。
    (题外话:其实分块是一个非常玄学的做法,块的大小不同,时间效率也会不同,我有很多次都是sqrtT了,乘或除一个常数就AC了。。。)

    参考模板

    这里以bzoj3343教主的魔法为例,放上参考模板一份。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    
    #ifdef WIN32
        #define LL "%I64d"
    #else
        #define LL "%lld"
    #endif
    
    #ifdef CT
        #define debug(...) printf(__VA_ARGS__)
        #define setfile() 
    #else
        #define debug(...)
        #define filename ""
        #define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
    #endif
    
    #define R register
    #define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
    #define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
    #define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
    #define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
    #define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
    char B[1 << 15], *S = B, *T = B;
    inline int FastIn()
    {
        R char ch; R int cnt = 0; R bool minus = 0;
        while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
        ch == '-' ? minus = 1 : cnt = ch - '0';
        while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
        return minus ? -cnt : cnt;
    }
    #define maxn 1000010
    #define maxsize 4010
    int a[maxn], b[maxn], block, id[maxn], n, q, ans, w, tag[maxsize];
    inline void build(R int x)
    {
        R int l = x * block, r = (x + 1) * block - 1;
        cmin(r, n);
        for (R int i = l; i <= r; ++i) b[i] = a[i];
        std::sort(b + l, b + r + 1);
    }
    inline void voi_query(R int l, R int r)
    {
        for (R int i = l; i <= r; ++i)
            if (a[i] >= w) ++ans;
    }
    inline void voi_add(R int l, R int r)
    {
        for (R int i = l; i <= r; ++i)
            a[i] += w;
        build(id[l]);
    }
    inline void query(R int x)
    {
        R int l = x * block, r = (x + 1) * block - 1;
        cmin(r, n);
        ans += (r - l + 1) - (std::lower_bound(b + l, b + r + 1, w - tag[x]) - b - l);
    }
    int main()
    {
    //  setfile();
        n = FastIn(), q = FastIn();
        block = sqrt(n);
        for (R int i = 1; i <= n; ++i) a[i] = FastIn();
        for (R int i = 1; i <= n; ++i) id[i] = i / block;
        for (R int i = 0; i <= n / block; ++i) build(i);
        for (R int i = 1; i <= q; ++i)
        {
            R char opt = getc();
            while (opt < 'A' || opt > 'Z') opt = getc();
            R int l = FastIn(), r = FastIn(); w = FastIn();
            if (opt == 'A')
            {
                ans = 0;
                if (id[l] == id[r]) voi_query(l, r);
                else
                {
                    voi_query(l, (id[l] + 1) * block - 1);
                    voi_query(id[r] * block, r);
                    for (R int i = id[l] + 1; i < id[r]; ++i)
                        query(i);
                }
                printf("%d
    ", ans );
            }
            else
            {
                if (id[l] == id[r]) voi_add(l, r);
                else
                {
                    voi_add(l, (id[l] + 1) * block - 1);
                    voi_add(id[r] * block, r);
                    for (R int i = id[l] + 1; i < id[r]; ++i)
                        tag[i] += w;
                }
            }
        }
        return 0;
    }

    刷题建议:

    BZOJ3343 教主的魔法
    BZOJ3463 [COCI2012] Inspector
    YZOJ1653 带区间修改的区间第k小
    BZOJ2724 [Violet 6]蒲公英
    BZOJ2453 维护队列
    BZOJ2821 作诗(Poetize)

  • 相关阅读:
    腾讯、阿里、网易、杰士邦等30家中秋月饼设计盘点!(完整版)
    腾讯、阿里、网易、杰士邦等30家中秋月饼设计盘点!(完整版)
    最挑战程序员的9大任务,你都干过哪些?
    这些代码优化的方法,你都用过吗?
    这些代码优化的方法,你都用过吗?
    6-13/6-14/6-15
    机器学习实验二-集成学习
    Windows下python3登陆和操作linux服务器
    什么是CDN?
    VI.应用-Trajectory Data Mining
  • 原文地址:https://www.cnblogs.com/cocottt/p/5550954.html
Copyright © 2011-2022 走看看