zoukankan      html  css  js  c++  java
  • 分块算法

    分块算法

    首先来谈谈什么是分块呢?直接理解就是把一个整体分成若干个部分,这就是所谓的字面理解分块。

    就如刚才所说,这就是分块的思想,而分块算法又称优雅的暴力

    好啦,现在我们正式来理解分块算法......

    一般来说,分块吗?你总要知道自己每块要分的大小对吧。这个已经解决了,一般每块都是分为sqrt(n)的大小,而一共有n / sqrt(n)块,当然,如果不能整除的话,你需要分的数量还是要加一的。之后你每块都要有一个标记吧,比如说:你有1,2,3,4,5这5个数,每块的大小是2, 一共3块, 其中 1 和 2 属于一块,3 和 4 属于一块,依次类推。一般存在一个belong[] 数组里面,方便后续操作。嘻嘻...你以为这样就完了吗?那你就错了,还需要一样东西,就是你需要记录每一块的范围,放心,这个很简单的,就是定义两个数组,分别记录在当前块所在范围的左端点和右端点。这个很容易实现的,就是上一个区间的右端点加一,和当前区间的右端点就是所求的范围。是不是有点晕,好吧。我们看一下代码吧,这样便于理解。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5+10;
    int a[maxn]; //a数组存取原始数据 int belong[maxn]; //belong数组表示每个数属于哪一块方便调用 int L[1010]; //L和R表示各块左右端点 int R[1010]; int block,num; //block各块大小,num块数量 //修改,视情况而定 void change(int l, int r, int add) { //略..(可见下面模板题) } //查询,同上 int query(int l, int r) { //略.. } //建立各块(各个分块这个操作大致一样) void build(int n) { block = sqrt(n);//每块的大小 num = n / block; //一共有多少块 if (n % block) { num++; //如果不整除显然数量加个1 } for(int i = 1; i <= num; i++) { L[i] = (i - 1) * block + 1; //上一个区间的右端点加一就是当前区间的左端点 R[i] = i * block; //直接计算当前区间的右端点 } R[num] = n; //最后一个右端点一定是结尾 for(int i = 1; i <= n; i++) { belong[i] = (i - 1) / block + 1; //belong数组 } //初始状态维护......(省略) }
    int main() { int n; scanf("%d", &n); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); } build(n); //询问......(省略) }
  • 相关阅读:
    367 Valid Perfect Square 有效的完全平方数
    365 Water and Jug Problem 水壶问题
    363 Max Sum of Rectangle No Larger Than K 最大矩阵和不超过K
    357 Count Numbers with Unique Digits 计算各个位数不同的数字个数
    SpringBoot (四) :thymeleaf 使用详解
    SpringBoot(三) :Spring boot 中 Redis 的使用
    SpringBoot(二) :web综合开发
    SpringBoot (一) :入门篇
    程序员最核心的竞争力是什么?
    Java面试题:多继承
  • 原文地址:https://www.cnblogs.com/buhuiflydepig/p/11219161.html
Copyright © 2011-2022 走看看