luo3372线段树模板的分块做法
题目大意
请你维护一个有n个元素的整数序列,要求支持区间查询&区间修改
对于100%的数据,\(1<=n<=10^5\)
分析
正常做法是线段树维护区间修改、区间查询,今天我要讲的是一种暴力做法:分块
分块的思想并不复杂,分块把一个长度为n的区间分成num段,操作时如果是整段用标记修改,不是整段的部分暴力修改
分析时间复杂度:在这题中,每段的标记修改是\(O(1)\)的,最多有num段,整段标记修改所用时间是\(O(num)\)的;不是整段的部分最多有\(O(n/num)\)个,暴力修改所用的时间是\(O(n/num)\)的;所以总时间是\(O(num+n/num)\)。
根据基本不等式,num取\(\sqrt n\)时该式有最小值;所以num取\(\sqrt n\)。
实现
分块的思想并不复杂,时间复杂度也不玄学,但是实现起来并不方便(可能是我弱)
分块的修改/查询都分为2部分:
- 整块的修改
- “零头”的修改
整块的修改是否简便:add[i] += val;
“零头”的修改直接修改,同时不要忘了维护所在块的信息:
a[i] += val;
sum[id[i]] += val;
修改就愉快地解决了,查询和修改差不多。
完整代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn = 100007;
int n, m, num, id[maxn];
long long sum[1000], add[1000], a[maxn];
int main(){
scanf("%d%d", &n, &m);
num = sqrt(n);
for (int i = 1; i <= n; ++i){
scanf("%lld", &a[i]);
id[i] = (i-1) / num;
sum[id[i]] += a[i];
}
while (m--){
int d; scanf("%d", &d);
if (d==1){
int x, y, C; scanf("%d%d%d", &x, &y, &C);
int Leftid = (x-1) / num + 1;
int Rightid = (y-1) / num - 1;
long long res = 0;
for (int i = Leftid; i <= Rightid; ++i)
add[i] += C;
for (int i = x; i <= Leftid * num; ++i)
a[i] += C, sum[id[i]] += C;
for (int i = (Rightid+1)*num+1; i <= y; ++i)
a[i] += C, sum[id[i]] += C;
}else{
int x, y; scanf("%d%d", &x, &y);
int Leftid = (x-1) / num + 1;
int Rightid = (y-1) / num - 1;
if (id[x] == id[y]){
long long res = 0;
for (int i = x; i <= y; ++i)
res += a[i] + add[id[i]];
printf("%lld\n", res);
continue;
}
long long res = 0;
for (int i = Leftid; i <= Rightid; ++i)
res += sum[i] + add[i] * num;
for (int i = x; i <= Leftid * num; ++i)
res += a[i] + add[Leftid-1];
for (int i = (Rightid+1)*num+1; i <= y; ++i)
res += a[i] + add[Rightid+1];
printf("%lld\n", res);
}
}
return 0;
}
luo3372线段树模板的分块做法的更多相关文章
- 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块
!!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...
- [AHOI 2009] 维护序列(线段树模板题)
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...
- hdu1754 I hate it线段树模板 区间最值查询
题目链接:这道题是线段树,树状数组最基础的问题 两种分类方式:按照更新对象和查询对象 单点更新,区间查询; 区间更新,单点查询; 按照整体维护的对象: 维护前缀和; 维护区间最值. 线段树模板代码 # ...
- P3373 线段树模板
好,这是一个线段树模板. #include <cstdio> using namespace std; ; long long int sum[N],tag1[N],tag2[N],mo; ...
- 线段树模板hdu 1754:I Hate It
I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- UESTC - 1057 秋实大哥与花 线段树模板题
http://acm.uestc.edu.cn/#/problem/show/1057 题意:给你n个数,q次操作,每次在l,r上加上x并输出此区间的sum 题解:线段树模板, #define _CR ...
- POJ 3468 A Simple Problem with Integers(线段树模板之区间增减更新 区间求和查询)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 140120 ...
- hdu 4819 二维线段树模板
/* HDU 4819 Mosaic 题意:查询某个矩形内的最大最小值, 修改矩形内某点的值为该矩形(Mi+MA)/2; 二维线段树模板: 区间最值,单点更新. */ #include<bits ...
- POJ3468:A Simple Problem with Integers(线段树模板)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 149972 ...
随机推荐
- 2018-2019-2 《Java程序设计》第5周学习总结
20175319 2018-2019-2 <Java程序设计>第5周学习总结 教材学习内容总结 本周学习<Java程序设计>第六章: 接口 实现接口 接口的UML图 接口回调 ...
- 第六节: 六类Calander处理六种不同的时间场景
背景介绍及其使用 该章节主要补充介绍,在前一章四类触发器的基础上配合六大Canlander来动态删减某些时间,来满足更多的应用场景. 1. DailyCalendar:动态排除某天的某些字段. (需求 ...
- H5取经之路——随便写点儿
[相对定位] * 1.使用position:relative:设置元素为相对定位的元素: * 2.定位机制: ①相对于自己原来文档流中的的位置定位,当不指定top等定位值时,不会改变元素位置: ②相对 ...
- angularjs指令中的compile与link函数详解补充
通常大家在使用ng中的指令的时候,用的链接函数最多的是link属性,下面这篇文章将告诉大家complie,pre-link,post-link的用法与区别. angularjs里的指令非常神奇,允许你 ...
- 智联python 技能摘取
- 2018-2019-1 20165234 实现mypwd
实现mypwd(选做,加分) 1 学习pwd命令 2 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 3 实现mypwd 4 测试mypwd 提交过程博客的链接
- 数位dp 的简单入门
时间紧张,就不讲那么详细了. 之前一直被深搜代码误解,以为数位dp 其实就是记忆化深搜...(虽说爆搜确实很舒服而且还好想) 但是后来发现数位dp 的标准格式其实是 预处理 + dp ...... 数 ...
- Linux 运维工作中的经典应用ansible(批量管理)Docker容器技术(环境的快速搭建)
一 Ansible自动化运维工具 Python 在运维工作中的经典应用 ansible(批量管理操作) .安装ansible(需要bese epel 2种源) wget -O /etc/yum.rep ...
- 【原创】大叔经验分享(44)hdfs副本数量
当hdfs空间不足时,除了删除临时数据或垃圾数据之外,还可以适当调整部分大目录的副本数量,多管齐下: 1 查看 $ hdfs dfs -ls /user/hive/warehouse/temp.db/ ...
- 行为驱动:Cucumber + Selenium + Java(一) - Cucumber简单操作实例
场景(Scenarios) 场景是Cucumber结构的核心之一.每个场景都以关键字“Scenario:”(或本地化一)开头,后面是可选的场景标题.每个Feature可以有一个或多个场景,每个场景由一 ...