题目大意

请你维护一个有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;

“零头”的修改直接修改,同时不要忘了维护所在块的信息:

  1. a[i] += val;
  2. sum[id[i]] += val;

修改就愉快地解决了,查询和修改差不多。

完整代码

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<cmath>
  5. using namespace std;
  6. const int maxn = 100007;
  7. int n, m, num, id[maxn];
  8. long long sum[1000], add[1000], a[maxn];
  9. int main(){
  10. scanf("%d%d", &n, &m);
  11. num = sqrt(n);
  12. for (int i = 1; i <= n; ++i){
  13. scanf("%lld", &a[i]);
  14. id[i] = (i-1) / num;
  15. sum[id[i]] += a[i];
  16. }
  17. while (m--){
  18. int d; scanf("%d", &d);
  19. if (d==1){
  20. int x, y, C; scanf("%d%d%d", &x, &y, &C);
  21. int Leftid = (x-1) / num + 1;
  22. int Rightid = (y-1) / num - 1;
  23. long long res = 0;
  24. for (int i = Leftid; i <= Rightid; ++i)
  25. add[i] += C;
  26. for (int i = x; i <= Leftid * num; ++i)
  27. a[i] += C, sum[id[i]] += C;
  28. for (int i = (Rightid+1)*num+1; i <= y; ++i)
  29. a[i] += C, sum[id[i]] += C;
  30. }else{
  31. int x, y; scanf("%d%d", &x, &y);
  32. int Leftid = (x-1) / num + 1;
  33. int Rightid = (y-1) / num - 1;
  34. if (id[x] == id[y]){
  35. long long res = 0;
  36. for (int i = x; i <= y; ++i)
  37. res += a[i] + add[id[i]];
  38. printf("%lld\n", res);
  39. continue;
  40. }
  41. long long res = 0;
  42. for (int i = Leftid; i <= Rightid; ++i)
  43. res += sum[i] + add[i] * num;
  44. for (int i = x; i <= Leftid * num; ++i)
  45. res += a[i] + add[Leftid-1];
  46. for (int i = (Rightid+1)*num+1; i <= y; ++i)
  47. res += a[i] + add[Rightid+1];
  48. printf("%lld\n", res);
  49. }
  50. }
  51. return 0;
  52. }

luo3372线段树模板的分块做法的更多相关文章

  1. 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块

    !!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...

  2. [AHOI 2009] 维护序列(线段树模板题)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...

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

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

  4. P3373 线段树模板

    好,这是一个线段树模板. #include <cstdio> using namespace std; ; long long int sum[N],tag1[N],tag2[N],mo; ...

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

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

  6. UESTC - 1057 秋实大哥与花 线段树模板题

    http://acm.uestc.edu.cn/#/problem/show/1057 题意:给你n个数,q次操作,每次在l,r上加上x并输出此区间的sum 题解:线段树模板, #define _CR ...

  7. POJ 3468 A Simple Problem with Integers(线段树模板之区间增减更新 区间求和查询)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 140120 ...

  8. hdu 4819 二维线段树模板

    /* HDU 4819 Mosaic 题意:查询某个矩形内的最大最小值, 修改矩形内某点的值为该矩形(Mi+MA)/2; 二维线段树模板: 区间最值,单点更新. */ #include<bits ...

  9. POJ3468:A Simple Problem with Integers(线段树模板)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 149972 ...

随机推荐

  1. 关于confluence上传文件附件预览查看时出现乱码的问题解决办法

    在confluence上传excel文件,预览时发现乱码问题主要是因为再上传文件的时候一般是Windows下的文件上传,而预览的时候,是linux下的环境,由于linux下没有微软字体,所以预览的时候 ...

  2. 剑指Offer_编程题_25

    题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数中的节点引用,否 ...

  3. NOI-OJ 2.2 ID:6261 汉诺塔

    思路 汉诺塔是递归思想最经典的例子,通过递归不断缩小问题,将n个盘子的问题简化n-1个,直至1个. 三个盘子,分别为A:from,B:to,C:by(A为起点盘,B为目标盘,C为中转盘) 过程 将1- ...

  4. 16、爬取知乎大v张佳玮的文章“标题”、“摘要”、“链接”,并存储到本地文件

    爬取知乎大v张佳玮的文章“标题”.“摘要”.“链接”,并存储到本地文件 # 爬取知乎大v张佳玮的文章“标题”.“摘要”.“链接”,并存储到本地文件 # URL https://www.zhihu.co ...

  5. Linux 一块网卡配置多个IP的方法

    1:ifconfig eth0:0 192.168.211.200/24 up 2:ip addr add 192.168.211.201/24 dev eth0 labe eth0:1 man ip ...

  6. java对象在内存中的结构

    在HotspotJVM中,32位机器下,Integer对象的大小是int的几倍? 我们都知道在java语言规范已经规定了int的大小是4个字节,那么Integer对象的大小是多少呢?要知道一个对象的大 ...

  7. Linux vi 编辑器常见命令的使用

    Linux vi 编辑器常见命令的使用 Linux下的文本编辑器有很多种,vi 是最常用的,也是各版本Linux的标配.注意,vi 仅仅是一个文本编辑器,可以给字符着色,可以自动补全,但是不像 Win ...

  8. Django对于模型的数据操作

    一.引入模型的包 from myApp.models import Grades,Students 二.查询所有数据 #objecs是类的隐藏属性:类名.objects.all()可以查询所有数据 G ...

  9. JAVA进阶13

    间歇性混吃等死,持续性踌躇满志系列-------------第13天 1.查看线程的运行状态 package code0327; class Demo01 implements Runnable { ...

  10. 330 div+css Experience

    今天学习的div,感觉对编辑html更为方便快捷,但还是需要多练,多熟悉一下思路和逻辑方式 越来越感觉,代码不是重要的,重要的是方向和思路,am的float clearfloat 及属性,还有over ...