题目大意

请你维护一个有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. R语言str_trim函数去除字符串中头部和尾部的空格
  2. SQLServer之创建非聚集索引
  3. SpringBoot整合Mybatis超详细流程
  4. java web微服务是什么_java微服务是什么
  5. 安装docx模块出现Import Error: No module named 'exceptions'的解决方案
  6. mysql 单表卡死
  7. SQL2005实现全文检索的步骤 停止数据库的用户连接
  8. SAP Spartacus B2B 页面的 Popup Component
  9. 无心剑随感《爱心教育》
  10. 可以扦插的花有哪些?
  11. 微信小程序 网学习址
  12. Pannellum:实例之全景图自动旋转
  13. LNMP架构 源码安装nginx+mysql+php+memcache+论坛
  14. GJB 测试报告(模板)
  15. jpg格式的矢量化arcgis_ArcGIS实践教程(11)图形的批量矢量化
  16. 计算机3c,计算机3C认证办理介绍
  17. Oracle 应用篇+Oracle Siebel CRM
  18. Zookeeper选举机制
  19. exchange2016卸载报错安装程序无法卸载,因为mscorsvw(9476)具有打开的文件
  20. 小程序marker callout 遇到的坑

热门文章

  1. 反卷积(Transposed conv deconv)实现原理(通俗易懂)
  2. 异或运算规则及其应用
  3. VM虚拟机安装系统出现Operating System not found 错误解决方法(附:系统安装完整步骤)
  4. 用Docker 构建RabbitMQ shovel(动态)
  5. Web APIs,BOM树,声明dom对象,年会抽奖案例,随机图片,表单,用户注册倒计时,innerHTNL,classList的使用
  6. MySQL技术内幕 InnoDB存储引擎——第2章 InnoDB存储引擎(未完待续)
  7. iPhone微信浏览器中jQuery发起post请求无效
  8. 金额达 500 亿美元,AMD 完成收购赛灵思
  9. 深圳公司法人变更的条件是什么?
  10. 港科夜闻丨“香港科大+资金”双资源向南海企业开放