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;
}
转载于:https://www.cnblogs.com/YJZoier/p/9721774.html
luo3372线段树模板的分块做法相关推荐
- 【线段树】[LUOGU 守墓人] [LUOGU 维护序列] 线段树模板题
题目: 题目链接:[LUOGU 守墓人] 题解: 线段树单点修改,区间修改,单点查询,区间查询,一系列线段树基本操作,模板打就好. (回头再补一个分块和树状数组的这种板子题,就是用分块和树状数组再写一 ...
- hdu1156(简单线段树 模板题)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- 线段树模板hdu 1754:I Hate It
I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- hdu1754 I hate it线段树模板 区间最值查询
题目链接:这道题是线段树,树状数组最基础的问题 两种分类方式:按照更新对象和查询对象 单点更新,区间查询; 区间更新,单点查询; 按照整体维护的对象: 维护前缀和; 维护区间最值. 线段树模板代码 # ...
- 【AHOI2009】【BZOJ1798】Seq 维护序列seq(线段树模板,易错提醒)
problem 给定一个长为n的序列,m次询问 每次询问有3种操作 1.一段区间全部乘一个值 2.一段区间全部加一个值 3.询问一段区间和%P solution 不就一颗线段树么,看朕10分钟A掉.. ...
- 洛谷3373 线段树模板
题目详情:https://www.luogu.org/problemnew/show/P3373 这个线段树模板写的头疼(最后纠错发现一个long long没开差点一口血喷出来),思路就是在普通的求区 ...
- ccf除法-线段树模板
这题的要求是对区间处理,查询区间和,一看就是线段树模板题,下面是代码 #include<iostream> using namespace std; int pp[100001]; str ...
- 线段树模板题3:区间染色问题
1.3线段树模板题3:区间染色问题 在DotA游戏中,帕吉的肉钩实际上是大多数英雄中最恐怖的东西.挂钩由长度相同的几个连续的金属棍组成. 现在,帕吉(Pudge)希望对挂接进行一些操作. 让我们将钩子 ...
- Just a Hook(线段树模板)
题意 n个铜棒子,对其进行区间修改,将区间中的棒子价值增加,问最后所有棒子的总价值是多少. 铜棒:1 银棒:2 金棒:3 思路 线段树模板题 建树时,每个节点值都为1,对其进行区间修改 最后输出根节点 ...
最新文章
- 苹果公司开发Overton机器学习平台,它到底是什么?
- 使用AOP+Annotation实现操作日志记录
- php运算符的特殊用法
- Liferay –简单主题开发
- JavaScript中的运算符
- flowable实现流程回退功能
- 爬虫-代理的质量控制
- 未能加载文件或程序集 请移除注册表值 [HKLM/Software/Microsoft/Fusion!EnableLog] 解决方法
- VS实用的几个快捷键
- DirectX9:先导篇 图形学基础
- time datetime
- 使用ERStudio创建数据表ER图并导出数据表的SQL(DDL)语句
- 【SQL注入-01】SQL语句基础及SQL注入漏洞原理及分类
- redimine 插件_3DMine软件与国内外同类软件对比
- c语言计算sum,C++ partial_sum(STL partial_sum)部分和计算方法详解
- html和js制作个人所得税表格,用JS编写个人所得税计算器
- 在火狐3中安装google工具栏
- viper4android 2.5正版,VIPER4Android最新版本
- 跳石头 解题报告【二分答案】
- 计算机学情问卷调查报告,学情调查报告及调查问卷(共9篇).docx