题目大意:分块维护一个有 n 个数字的序列,有两种操作:区间加,区间查询小于某个数的元素个数。n <= 50000

预处理阶段:处理出块内元素的相对大小顺序(排序),时间复杂度为 \(O(nlogn)\)

查询阶段:区间加过程中每次重构的时间复杂度为 \(O(\sqrt n*log\sqrt n)\),查询过程中每次时间复杂度为 \(O(\sqrt n)\),一共 n 次操作。

因此,总时间复杂度为 \(O(n*logn+n*\sqrt n*log\sqrt n)\)

注:该题无法用树套树进行维护,树套树一般仅支持单点修改,平衡树区间修改操作会很慢。

分块比树套树优秀的地方在于维护的信息仅在块中处理即可,无需像树一样进行上传,即:无需考虑维护信息的区间合并性质。

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=5e4+10;
const int maxb=800; inline int read(){
int x=0,f=1;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
return f*x;
} int n,m,a[maxn];
struct node{int l,r,add;}b[maxb];
int tot,bl[maxn];vector<int> v[maxb];
void make_block(){
tot=sqrt(n);
for(int i=1;i<=tot;i++)b[i].l=b[i-1].r+1,b[i].r=i*tot;
if(b[tot].r<n)++tot,b[tot].l=b[tot-1].r+1,b[tot].r=n;
for(int i=1;i<=tot;i++){
for(int j=b[i].l;j<=b[i].r;j++)bl[j]=i,v[i].push_back(a[j]);
sort(v[i].begin(),v[i].end());
}
}
inline void rebuild(int idx){
v[idx].clear();
for(int i=b[idx].l;i<=b[idx].r;i++)v[idx].push_back(a[i]);
sort(v[idx].begin(),v[idx].end());
}
void modify(int l,int r,int val){
int x=bl[l],y=bl[r];
if(x==y){
for(int i=l;i<=r;i++)a[i]+=val;
rebuild(x);
}else{
for(int i=x+1;i<=y-1;i++)b[i].add+=val;
for(int i=l;i<=b[x].r;i++)a[i]+=val;
for(int i=b[y].l;i<=r;i++)a[i]+=val;
rebuild(x),rebuild(y);
}
}
int query(int l,int r,int val){
int ans=0,x=bl[l],y=bl[r];
if(x==y){
for(int i=l;i<=r;i++)if(a[i]<val-b[x].add)++ans;
}else{
for(int i=x+1;i<=y-1;i++)ans+=lower_bound(v[i].begin(),v[i].end(),val-b[i].add)-v[i].begin();
for(int i=l;i<=b[x].r;i++)if(a[i]<val-b[x].add)++ans;
for(int i=b[y].l;i<=r;i++)if(a[i]<val-b[y].add)++ans;
}
return ans;
} int main(){
n=m=read();
for(int i=1;i<=n;i++)a[i]=read();
make_block();
while(m--){
int opt=read(),l=read(),r=read(),val=read();
if(opt==0)modify(l,r,val);
else if(opt==1)printf("%d\n",query(l,r,val*val));
}
return 0;
}

【LOJ#6278】数列分块2的更多相关文章

  1. LOJ #6278. 数列分块入门 2-分块(区间加法、查询区间内小于某个值x的元素个数)

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

  2. LOJ#6278. 数列分块入门 2

    在一个区间上进行操作,一种操作是某个小区间都加上c,另一个查找这个区间内大于c*c的数 我们可以另外开一个数组在保存a中的每个分块内的相对值,然后每次对a加值,并把a的值赋给b,不同的是b内的各个分块 ...

  3. LOJ 6278 数列分块入门2

    [题解] 分块.块内排序.块内二分出第一个大于等于c的数. #include<cstdio> #include<algorithm> #include<cmath> ...

  4. LOJ——#6277. 数列分块入门 1

    ~~推荐播客~~ 「分块」数列分块入门1 – 9 by hzwer 浅谈基础根号算法——分块 博主蒟蒻,有缘人可直接观摩以上大佬的博客... #6277. 数列分块入门 1 题目大意: 给出一个长为 ...

  5. #6278. 数列分块入门 2(询问区间内小于某个值 xx 的元素个数)

    题目链接:https://loj.ac/problem/6278 题目大意:中文题目 具体思路:数列分块模板题,对于更新的时候,我们通过一个辅助数组来进行,对于原始的数组,我们只是用来加减,然后这个辅 ...

  6. LOJ 6277-6280 数列分块入门 1-4

    数列分块是莫队分块的前置技能,练习一下 1.loj6277 给出一个长为n的数列,以及n个操作,操作涉及区间加法,单点查值. 直接分块+tag即可 #include <bits/stdc++.h ...

  7. LOJ #6285. 数列分块入门 9-分块(查询区间的最小众数)

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

  8. LOJ #6284. 数列分块入门 8-分块(区间查询等于一个数c的元素,并将这个区间的所有元素改为c)

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

  9. LOJ #6283. 数列分块入门 7-分块(区间乘法、区间加法、单点查询)

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

  10. LOJ #6282. 数列分块入门 6-分块(单点插入、单点查询、数据随机生成)

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

随机推荐

  1. 阿里云Centos搭建jdk环境

    当我们开始了自己的开发,那么云服务器是一定少不了的,当然也有很多同学只是在本地做开发研究. 这里记录一下我自己在阿里云上搭建环境的过程. 趁着优惠的时候,我在阿里云上购买了ECS云服务器,并且搭载了C ...

  2. Web系统页面打印技术实现与分析

    1 Web页面打印概述应用WEB化,不论对开发商,还是对用户来说,实在是一种很经济的选择,因为基于WEB的应用,客户端的规则很简单,容易学习,容易维护,容易发布.在WEB系统中,打印的确是个烦人的问题 ...

  3. SCRUM 12.19

    我们的爬虫依然存在一些问题,我们决定暂时将大家的工作重心放在爬虫上. 新的任务分配如下 成员 原本任务 新任务 彭林江 落实API 研究美团爬虫 郝倩 研究遍历美团数据方法 研究遍历美团数据方法 牛强 ...

  4. 20135337——Linux内核分析:第十七章 模块与设备

    第17章 模块与设备 设备类型:在所有 Unix 系统中为了统一普通设备的操作所采用的分类. 模块: Linux 内核中用于按需加载和卸载目标码的机制. 内核对象:内核数据结构中支持面向对象的简单操作 ...

  5. <软件体系结构>实验框架选择及其说明

    一.框架选择 本次实验,我所采取的框架是SSH框架.那么首先,我想简单的说明一下SSH框架,一方面给自己复习一下知识,另一方面也能使自己在以后看这篇博客的时候不至于太费力. SSH不是一个框架,而是S ...

  6. QT 窗口置顶功能

    Qt中,保持窗口置顶的设置为: Qt::WindowFlags m_flags = windowFlags(); setWindowFlags(m_flags | Qt::WindowStaysOnT ...

  7. Python 安装 OpenCV 遇到的问题

    从 python下了 opencv_python-3.3.1+contrib-cp36-cp36m-win_amd64.whl [python 3.6  os win10 64  IDE Pychar ...

  8. java数值运算后精度丢失问题

    最近连续俩次遇到运算后数值精度丢失问题,所以记录一下. 问题1:java计算百分比,应该得到57,可返回的就是56 在java代码中 BigDecimal progress; BigDecimal a ...

  9. [转帖]GitHub上整理的一些工具

    GitHub上整理的一些工具   技术站点 Hacker News:非常棒的针对编程的链接聚合网站 Programming reddit:同上 MSDN:微软相关的官方技术集中地,主要是文档类 inf ...

  10. python decimal.quantize()参数rounding的各参数解释与行为

    我最开始其实是由于疑惑ROUND_FLOOR和 ROUND_DOWN的表现区别才看了一波文档,但是感觉拉出一票以前没有留意过的东西. 贴一个decimal文档里面的解释: ROUND_CEILING ...