Description

有一个N个整数的序列(每个数的初值为0)。每个数都是整数。你有M次操作。操作有两种类型:

——Add  Di  Xi 从第一个数开始每隔Di 个位置增加Xi

——Query Li  Ri 回答当前序列Li项到Ri项的和

Input

两个数N和M,输入到文件结尾。以下M行每行的输入两种操作形式的一种。(1 <= N, M, Di, Xi, Li, Ri <= 100000, Li <= Ri )

Output

对于每组数据,输出每组的询问的结果。

Sample Input

4 4
Query 2 3
Add 1 1
Query 2 3
Query 1 4

Sample Output

0
2
4

HINT

Source


这道题出自2013年国家队候选队员罗剑桥的论文《浅谈分块思想在一类数据处理问题中的应用》,是罗原创的一道题。

这道题的解法是分块:

将整个区间从左往右每$\lceil\sqrt{n}\rceil$个分成一块。

更新:

将$ADD\quad D \ X$操作分成两类

  1.   $D \ge \lceil\sqrt{n} \rceil$ 的$ADD$操作,直接更新序列相应位置上元素,并更新各元素所属块由这类$ADD$操作所贡献的和,复杂度是$O(\sqrt{n})$。
  2. $D < \lceil \sqrt{n} \rceil$ 的$ADD$操作,我们将它记录在数组$sum[1\dots\lceil \sqrt{n} \rceil -1]$上:即对于$ADD \quad D \ X$,将$X$累加在$sum[D]$上,复杂度是$O(1)$。

查询:

对于查询区间$[L, R]$,分别查询上述两类$ADD$操作对$[L, R]$的贡献,相加即是答案。


Implementation:

这题我调了很长时间,先贴上第一版(有bug)代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. typedef long long LL;
  5. const int N(1e5+);
  6. int n, m, b;
  7. LL bucket[N], sum[N], a[N];
  8. char op[];
  9.  
  10. inline int ID(int x, int b){ //x>=0
  11. return x? (x-)/b+: ;
  12. }
  13.  
  14. int main(){
  15. for(int T=; ~scanf("%d%d", &n, &m); T++){
  16. if(T==) for(;;);
  17. memset(a, , sizeof(a));
  18. memset(bucket, , sizeof(bucket));
  19. memset(sum, , sizeof(sum));
  20. b=sqrt(n);
  21. for(int d, x, l, r; m--; ){
  22. scanf("%s", op);
  23. if(*op=='A'){
  24. scanf("%d%d", &d, &x);
  25. if(d>=b){
  26. for(int i=; i<=n; i+=d)
  27. a[i]+=x, bucket[ID(i, b)]+=x;
  28. }
  29. else sum[d]+=x;
  30. }
  31. else{
  32. scanf("%d%d", &l, &r);
  33. LL res=;
  34. int L=ID(l-, b)+, R=ID(r+, b)-; //error-prone
  35. ////////////////////////////////////////
  36. for(int i=l; i<=b*(L-); i++) res+=a[i];
  37. for(int i=b*R+; i<=r; i++) res+=a[i];
  38. ////////////////////////////////////////
  39. for(int i=L; i<=R; i++) res+=bucket[i];
  40. for(int i=; i<b; i++){
  41. res+=(ID(r, i)-ID(l-, i))*sum[i];
  42. }
  43. printf("%lld\n", res);
  44. }
  45. }
  46. }
  47. return ;
  48. }

bug就在分离出来的那两行,坑暂时留着,以后填。

bug-free version

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. typedef long long LL;
  5. const int N(1e5+);
  6. int n, m, b, id[N];
  7. LL bucket[N], sum[N], a[N];
  8. char op[];
  9.  
  10. LL SUM(int x){
  11. LL res=;
  12. int R=id[x+]-;
  13. for(int i=; i<=R; i++) res+=bucket[i];
  14. for(int i=R*b+; i<=x; i++) res+=a[i];
  15. for(int i=; i<b; i++) res+=((x-)/i+)*sum[i];
  16. return res;
  17. }
  18.  
  19. int main(){
  20. for(; ~scanf("%d%d", &n, &m); ){
  21. memset(a, , sizeof(a));
  22. memset(bucket, , sizeof(bucket));
  23. memset(sum, , sizeof(sum));
  24. b=sqrt(n);
  25. for(int i=; i<=n+; i++) id[i]=(i-)/b+;
  26. for(int d, x, l, r; m--; ){
  27. scanf("%s", op);
  28. if(*op=='A'){
  29. scanf("%d%d", &d, &x);
  30. if(d>=b) for(int i=; i<=n; i+=d) a[i]+=x, bucket[id[i]]+=x;
  31. else sum[d]+=x;
  32. }
  33. else scanf("%d%d", &l, &r), printf("%lld\n", SUM(r)-SUM(l-));
  34. }
  35. }
  36. return ;
  37. }

DLUTOJ #1306 Segment Tree?的更多相关文章

  1. BestCoder#16 A-Revenge of Segment Tree

    Revenge of Segment Tree Problem Description In computer science, a segment tree is a tree data struc ...

  2. [LintCode] Segment Tree Build II 建立线段树之二

    The structure of Segment Tree is a binary tree which each node has two attributes startand end denot ...

  3. [LintCode] Segment Tree Build 建立线段树

    The structure of Segment Tree is a binary tree which each node has two attributes start and end deno ...

  4. Segment Tree Modify

    For a Maximum Segment Tree, which each node has an extra value max to store the maximum value in thi ...

  5. Segment Tree Query I & II

    Segment Tree Query I For an integer array (index from 0 to n-1, where n is the size of this array), ...

  6. Segment Tree Build I & II

    Segment Tree Build I The structure of Segment Tree is a binary tree which each node has two attribut ...

  7. Lintcode: Segment Tree Query II

    For an array, we can build a SegmentTree for it, each node stores an extra attribute count to denote ...

  8. Lintcode: Segment Tree Modify

    For a Maximum Segment Tree, which each node has an extra value max to store the maximum value in thi ...

  9. Lintcode: Segment Tree Query

    For an integer array (index from 0 to n-1, where n is the size of this array), in the corresponding ...

随机推荐

  1. 使用CSS3制作72个webapp图标

    前言 移动网络带宽的快慢直接影响webapp应用体验效果的优差,其中加载图片是很耗流量的,所以对这一方面的性能优化是很需要的.一般对于那些小而多的图片(图标)都会采用sprite合并成一张图片来减少h ...

  2. Ruby Web实时消息后台服务器推送技术---GoEasy

    越来越多的项目需要用到实时消息的推送与接收,怎样用Ruby实现最方便呢?我这里推荐大家使用GoEasy, 它是一款第三方推送服务平台,使用它的API可以轻松搞定实时推送! 浏览器兼容性:GoEasy推 ...

  3. 华为访问列表traffic-policy案例

    1,最近某公司有个需求 2,配置为重点--在于思路 需求:192.168.1 3 5 8网段不能访问2.x网段 仅允许财务2.x访问1.253打印机. acl name permit_printer ...

  4. php基础11:运算符

    <?php $a = 5; $b = ++$a; echo '$a'.$a; echo "<br>"; echo '$b'.$b; echo "< ...

  5. php基础04:字符串函数

    <?php //1.strlen(),strlen() 函数返回字符串的长度,以字符计. echo strlen("hello world"); echo "< ...

  6. js copy

    Javascript 实现复制(Copy)动作方法大全 投稿:hebedich 字体:[增加 减小] 类型:转载 时间:2014-06-20我要评论 现在浏览器种类也越来越多,诸如 IE.Firefo ...

  7. eclipse系列: Cannot change version of project facet Dynamic web的解决方法

    问题描述         用Eclipse创建Maven结构的web项目的时候选择了Artifact Id为maven-artchetype-webapp,由于这个catalog比较老,用的servl ...

  8. LeetCode:Unique Paths I II

    Unique Paths A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagra ...

  9. 信息安全系统设计基础第一次实验报告 20135201&&20135306&&20135307

    信息安全系统设计基础实验 班级: 201353 姓名:张忻 张嘉琪 黄韧 学号:20135301 20135307 20135306 实验日期:2015.11.10 实验名称: S3C2410的lin ...

  10. 讽刺的是,我在linux下使用最多的命令,竟然是windows的

    $ history | awk '{print $2}' | sort | uniq -c | sort -nr | head dir vi echo cd vim jobs gcc ls less ...