几个词语的相关解释:
区间:数列中连续一段的元素;
区间操作:将某个区间[a,b]的所有元素进行某种改动的操作
块:我们将数列划分为若干个不相交区间,每个区间称为一个块;
**整块**:在一个区间操作时,完整包含于区间的块
**不完整的块**:在一个区间操作时,只有部分包含于区间的块,即区间左右端点所在的两个块

分块入门 1

传送门

这是一道能用许多数据结构优化的经典题,可以用于不同数据结构训练。
数列分块就是把数列中每m个元素打包起来,达到优化算法的目的。

以此题为例,如果我们把每m个元素分成一块,共有n/m块。每次区间加的操作会涉及O(n/m)个整块,以及区间两侧不完整的块中至多2m个元素、

我们给每个块设置一个加法标记(就是记录这个块中元素一起加了多少),每次操作对每个整块直接O(1)标记,而不完整的块由于元素比较少,暴力修改元素的值。
每次询问返回元素的值加上其所在块的加法标记。
这样每次操作的复杂度都是O(n/m)+O(m).根据均值不等式,当m==sqrt(n)时复杂度最低,为了方便,我们默认下文的分块大小为sqrt(n);
这代码然人感觉很不讲道理,暴力,居然过了,而我只能用二叉树那种乱七八糟的东西。

#include<map>
#include<set>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define mod 998244353
#define pi acos(-1)
#define inf 0x7fffffff
#define ll long long
using namespace std;
ll read()
{ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}
int n,blo;//blo为块的长度
int v[50005],bl[50005],atag[50005];
void add(int a,int b,int c)
{for(int i=a; i<=min(bl[a]*blo,b); i++)//a在bl[a]里面,a到该块的结尾,需要加cv[i]+=c;if(bl[a]!=bl[b])//a,b不在同一个块内for(int i=(bl[b]-1)*blo+1; i<=b; i++)//b上一个块结尾加1到b加cv[i]+=c;for(int i=bl[a]+1; i<=bl[b]-1; i++)//a块与b块之间+c。atag[i]+=c;//加法标记
}
int main()
{n=read();//第一行数blo=sqrt(n);//分sqrt(n)个块for(int i=1; i<=n; i++)v[i]=read();//存储a[i];for(int i=1; i<=n; i++)bl[i]=(i-1)/blo+1;//初始化该位置包含在第几个块for(int i=1; i<=n; i++){int f=read(),a=read(),b=read(),c=read();//f,a,b,c分别是每一行的四个数if(f==0)add(a,b,c);if(f==1)printf("%d\n",v[b]+atag[bl[b]]);//返回元素的值加上所在块的加法标记。}return 0;
}

数列分块入门练习题一相关推荐

  1. #6279. 数列分块入门 3(区间修改,查询权值前驱)

    #6279. 数列分块入门 3 这是使用hzwer建议的set写的分块代码,set自动排序,支持二分查找,但是常数较大,比我下面写的用vector实现的分块慢了三倍,空间大了10倍. #include ...

  2. LOJ 数列分块入门6

    LOJ 数列分块入门6 题目: 题目 题解: 我都不懂这题为什么要用分块... ... 直接vector就好了... 但是如果有区间修改的话就不行了.所以这题是启示我们也可以动态分块.具体就是每次插入 ...

  3. LOJ #6280. 数列分块入门 4-分块(区间加法、区间求和)

    #6280. 数列分块入门 4 内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 题目描述 给出一个长为 ...

  4. 数列分块入门(套题)(loj6277,loj6278,loj6279,loj6280,loj6281,loj6282,loj6283,loj6284,loj6285)

    前言 zjoi考差了,码一些分块题缓解一下心情 壹 数列分块入门 1[loj6277] 题目大意:区间加,单点查 直接分块,区间加时完全覆盖的块打tag,边界块暴力重构 块大小设为n\sqrt nn​ ...

  5. 数列分块入门 (1 ~ 7)

    分块 6277. 数列分块入门 1 分块思想 我们把每m个元素分成一块,所以我们总共的块数就是n/mn / mn/m块,一般情况下我们取m=nm = \sqrt{n}m=n​.对于区间加操作,我们可以 ...

  6. 「分块」数列分块入门1 – 9

    ACM模板 放暑假了,回归!!! 自己不会写暴力,而且好久没写代码了,于是学学分块的优雅暴力~ 「分块入门-LibreOJ」 「分块」数列分块入门1 – 9 by hzwer 数列简单分块问题实际上有 ...

  7. 「分块系列」数列分块入门3 解题报告

    数列分块入门3 题意概括 区间加法,区间求前驱. 写在前面 这题的方法与分块2方法极其类似,建议自行解决. 正题 和上一题类似,但是二分不是用来计数的,而是用来求小于c的最大值的.然后对于不完整快,将 ...

  8. #6277. 数列分块入门 1

    题目链接:https://loj.ac/problem/6277 学习博客:http://hzwer.com/8053.html #6277. 数列分块入门 1 内存限制:256 MiB时间限制:10 ...

  9. #6279. 数列分块入门 3

    数列分块入门 3 #include<bits/stdc++.h> using namespace std; #define ll long long const int N=1000010 ...

最新文章

  1. OpenCV(十六)边缘检测2 -- Laplace(拉普拉斯)二阶微分算子
  2. 用XMing + Putty 凿出让Linux 图形界面在Windows裸奔的隧道
  3. dpkg ihr状态_考勤机数据无法同步
  4. 刷卡提示57能恢复吗_硬盘格式化之后数据还能恢复吗?
  5. ppt中的流程图怎么整体移动_PPT中图片太丑了?该怎么办?
  6. bash linux .ee,Linux下Bash shell学习笔记.md
  7. STM32外部中断具体解释
  8. # 研究杂感 × VOSviewer(第二辑)
  9. 制作自己的Maven镜像,上传Harbor镜像仓库
  10. 基于Python的Bangumi中动画片排行榜数据可视化分析
  11. 阿里巴巴字体图标库使用方法【前端类超详细】
  12. HTML5+CSS3笔记 (黑马pink老师)
  13. Jmeter读取CSV文件
  14. docker 常用命令(二)——容器命令
  15. Docker的镜像制作与整套项目一键打包部署
  16. 爬虫初学——爬取京东商品的评论(一)
  17. 雷达图 The number of FixedLocator locations (4), usually from a call to set_ticks, does not match the n
  18. 01--背包问题以及构造最优解
  19. android 采集cpu温度,阳光沙滩博客-Android开发如何读取到CPU,内存等硬件温度信息?...
  20. 仿生学的科技应用——蚁群算法简介

热门文章

  1. trim函数 html,trim函数的使用方法(你会用TRIMMEAN 函数吗?)
  2. MySQL中创建时间和更新时间的自动更新
  3. go 合并excel
  4. UI设计中图形设计详解
  5. 你不是不优秀,而是太着急
  6. 使用Jeb动态调试安卓的时候显示Could not attach to target
  7. 黑鲨重装计算机安装无法继续,黑鲨教你重装系统解决电脑开机无法进入系统问题...
  8. 13万人12306信息泄露 小伙挨个发邮件通知
  9. springboot整合jwt_springboot整合jwt实现身份验证
  10. Oracle Database XE(免费)的数据库下载安装使用教程-第一篇