题目大意

请你维护一个有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部分:

  1. 整块的修改
  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线段树模板的分块做法相关推荐

  1. 【线段树】[LUOGU 守墓人] [LUOGU 维护序列] 线段树模板题

    题目: 题目链接:[LUOGU 守墓人] 题解: 线段树单点修改,区间修改,单点查询,区间查询,一系列线段树基本操作,模板打就好. (回头再补一个分块和树状数组的这种板子题,就是用分块和树状数组再写一 ...

  2. hdu1156(简单线段树 模板题)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  3. 线段树模板hdu 1754:I Hate It

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  4. hdu1754 I hate it线段树模板 区间最值查询

    题目链接:这道题是线段树,树状数组最基础的问题 两种分类方式:按照更新对象和查询对象 单点更新,区间查询; 区间更新,单点查询; 按照整体维护的对象: 维护前缀和; 维护区间最值. 线段树模板代码 # ...

  5. 【AHOI2009】【BZOJ1798】Seq 维护序列seq(线段树模板,易错提醒)

    problem 给定一个长为n的序列,m次询问 每次询问有3种操作 1.一段区间全部乘一个值 2.一段区间全部加一个值 3.询问一段区间和%P solution 不就一颗线段树么,看朕10分钟A掉.. ...

  6. 洛谷3373 线段树模板

    题目详情:https://www.luogu.org/problemnew/show/P3373 这个线段树模板写的头疼(最后纠错发现一个long long没开差点一口血喷出来),思路就是在普通的求区 ...

  7. ccf除法-线段树模板

    这题的要求是对区间处理,查询区间和,一看就是线段树模板题,下面是代码 #include<iostream> using namespace std; int pp[100001]; str ...

  8. 线段树模板题3:区间染色问题

    1.3线段树模板题3:区间染色问题 在DotA游戏中,帕吉的肉钩实际上是大多数英雄中最恐怖的东西.挂钩由长度相同的几个连续的金属棍组成. 现在,帕吉(Pudge)希望对挂接进行一些操作. 让我们将钩子 ...

  9. Just a Hook(线段树模板)

    题意 n个铜棒子,对其进行区间修改,将区间中的棒子价值增加,问最后所有棒子的总价值是多少. 铜棒:1 银棒:2 金棒:3 思路 线段树模板题 建树时,每个节点值都为1,对其进行区间修改 最后输出根节点 ...

最新文章

  1. 苹果公司开发Overton机器学习平台,它到底是什么?
  2. 使用AOP+Annotation实现操作日志记录
  3. php运算符的特殊用法
  4. Liferay –简单主题开发
  5. JavaScript中的运算符
  6. flowable实现流程回退功能
  7. 爬虫-代理的质量控制
  8. 未能加载文件或程序集 请移除注册表值 [HKLM/Software/Microsoft/Fusion!EnableLog] 解决方法
  9. VS实用的几个快捷键
  10. DirectX9:先导篇 图形学基础
  11. time datetime
  12. 使用ERStudio创建数据表ER图并导出数据表的SQL(DDL)语句
  13. 【SQL注入-01】SQL语句基础及SQL注入漏洞原理及分类
  14. redimine 插件_3DMine软件与国内外同类软件对比
  15. c语言计算sum,C++ partial_sum(STL partial_sum)部分和计算方法详解
  16. html和js制作个人所得税表格,用JS编写个人所得税计算器
  17. 在火狐3中安装google工具栏
  18. viper4android 2.5正版,VIPER4Android最新版本
  19. 跳石头 解题报告【二分答案】
  20. 计算机学情问卷调查报告,学情调查报告及调查问卷(共9篇).docx

热门文章

  1. 1356: PIPI的保险箱
  2. java导入csv文件时利弊,关于在自己写的应用上导入csv文件时踩过的坑
  3. 【资源下载】超级好用的几款免费图床
  4. VML学习笔记(1)——基本概念
  5. 【8028】产品规划七宗罪
  6. 【全网首发最全】首届盘古石杯全国电子数据取证大赛晋级赛write up 2023年奇安信取证比赛 高清截图
  7. Redis的事务机制
  8. GeoHash转经纬度
  9. 车路协同自动驾驶数据集DAIR-V2X
  10. 记Mysql同时查询更新同一张表的操作