题目大意:分块维护一个有 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. 正则&highlight高亮实现(干货)

    写完正则表达式以后在浏览器上检测实在是不方便,于是就写了一个JS正则小工具,大大地提高了学习效率.学习之余用正则实现了一个highlight高亮demo,欢迎交流. 什么是正则表达式? 简单的说:正则 ...

  2. 点评qq浏览器

    1.内核.       qq浏览器用的是是IE8的内核,而且是只有IE内核,所以,在速度上没办法跟那些webkit内核做对比了,不过也没有太慢,在沈航的网速下,打开网页的速度也还是勉强可以接受的.   ...

  3. JAVA程序设计 实验一报告

    北京电子科技学院(BESTI) 实     验    报     告 课程:Java程序设计 班级:1351  姓名:李畅宇  学号:20135129 成绩:             指导教师:娄嘉鹏 ...

  4. GIthub地址

    https://github.com/cuibaoxue/Text1

  5. 201306114357-实验3-C语言

    #include<stdio.h>#include <stdlib.h>#include <time.h>main(){ int a,b,c,n,u,i,sum;  ...

  6. 20172319 《Java程序设计教程》第8周学习总结

    20172319 2018.04.24-05.03 <Java程序设计教程>第8周学习总结 目录 教材学习内容总结 教材学习中的问题和解决过程 代码调试中的问题和解决过程 代码托管 上周考 ...

  7. Selenium的自我总结2_元素基本操作

    对于Selenium的基本元素的操作,就自己的了解做了一个基本的介绍,这篇直接上代码,针对一个页面如何操作写了些基本的操作脚本,希望对初学者有一定的帮助,也希望通过这些总结让自己有一些清晰的认识和了解 ...

  8. [linux学习]sysctl 以及 net.ipv4.ip_forward

    1. sysctl 命令显示 当前系统的参数配置信息 显示全部配置信息 sysctl -a 帮助信息主要如下: [root@k8s-master ~]# sysctl -help Usage: sys ...

  9. c3算法详解

    c3 算法求某一类在多继承中的继承顺序:类的mro == [类] + [父类的继承顺序] + [父类2的继承顺序]如果从左到右的第一个类在后面的顺序中出现,那么就提取出来到mro顺序中[ABCD] + ...

  10. js對象構造

    創建對象的3種方式: 1. var a=new Object() a.attributes=“1”: 2. var a={attributes:"1",aa:"2&quo ...