以前似乎做过类似的不过当时完全不会。现在看到就有点思路了,开始还有洋洋得意得觉得自己有不小的进步了,结果思路错了。。。改了很久后测试数据过了还果断爆空间。。。

  给你一串数字A,然后是两种操作:

"1 l r k c":意思是当 l=<i<=r 对(i-a)%k = =0 的每个 Ai 都增加 c (1=<k<=10)

"2 i" :意思是求出 Ai

   一看就是区间更新和单点查询,其实可以用树状数组做,可是觉得线段树好弄一点,结果成功入坑。。。

  我们可以发现k特别的小,而对于每一位的k,都有k个不同的余数,所以可以从这儿入手。可以看出对于每一个k,难点在于区间更新的时候并不是一定严格+1的连续区间,但是一定是+k连续区间,所以:

k=1,建一棵从1开始每次+1的树

k=2,建一棵从1开始每次+2的树 建一颗从2开始每次+2的树

k=3,建一棵从1开始每次+3的树 建一颗从2开始每次+3的树 建一棵从3开始每次+3的树

......

建立55棵线段树

  但是如果就直接建立55颗线段树,再建55个对应的更新树,则会爆空间。不过我们可以看是单点查询,根本不需要用父节点记录孩子节点的和,建立线段树仅仅是为了区间更新。所以就可以直接模拟更新树,每个节点记录是此区间每个位置需要增加的值,求值的时候下更新到叶子节点就可以了。注意因为输入的l不是一定对应每棵树的l位置(不是每次都+1),所以我们要处理l,还有就是[l,r]之间我们仅仅更新一些点,右端点要处理好。最后查询的时候要查询10棵树

  本以为对线段树有些心得了,可是对于有一点变化的东西都不能灵活运用,还需努力了

  1. #include<set>
  2. #include<map>
  3. #include<queue>
  4. #include<stack>
  5. #include<cmath>
  6. #include<vector>
  7. #include<string>
  8. #include<cstdio>
  9. #include<cstring>
  10. #include<stdlib.h>
  11. #include<iostream>
  12. #include<algorithm>
  13. using namespace std;
  14. #define eps 1E-8
  15. /*注意可能会有输出-0.000*/
  16. #define Sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型
  17. #define Cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化
  18. #define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0
  19. #define mul(a,b) (a<<b)
  20. #define dir(a,b) (a>>b)
  21. typedef long long ll;
  22. typedef unsigned long long ull;
  23. const int Inf=<<;
  24. const double Pi=acos(-1.0);
  25. const int Max=<<;
  26. int segtr[Max][];//建立55棵线段树 因为是单点查询,所以每次查询到孩子节点,父节点就只需要记录孩子增加了多少,所以线段树节点就模拟更新的树就好
  27. int per[Max],pos[][];//记录初始值 记录节点在树的位置
  28. void Create(int sta,int enn,int now)
  29. {
  30. memset(segtr[now],,sizeof(segtr[now]));
  31. if(sta==enn)
  32. {
  33. scanf("%d",&per[sta]);
  34. return;
  35. }
  36. int mid=dir(sta+enn,);
  37. int next=mul(now,);
  38. Create(sta,mid,next);
  39. Create(mid+,enn,next|);
  40. return;
  41. }
  42. void Downow(int now,int next,int k)//区间更新的关键
  43. {
  44. if(segtr[now][k])//相当于区间更新
  45. {
  46. segtr[next][k]+=segtr[now][k];
  47. segtr[next|][k]+=segtr[now][k];
  48. segtr[now][k]=;
  49. }
  50. return;
  51. }
  52. void Update(int sta,int enn,int now,int x,int y,int k,int add)
  53. {
  54. if(sta>=x&&enn<=y)
  55. {
  56. segtr[now][k]+=add;
  57. return;
  58. }
  59. int mid=dir(sta+enn,);
  60. int next=mul(now,);
  61. Downow(now,next,k);//只需要下更新
  62. if(mid>=x)
  63. Update(sta,mid,next,x,y,k,add);
  64. if(mid<y)
  65. Update(mid+,enn,next|,x,y,k,add);
  66. return;
  67. }
  68. int Query(int sta,int enn,int now,int x,int k)
  69. {
  70. if(sta==enn)
  71. {
  72. return segtr[now][k];
  73. }
  74. int mid=dir(sta+enn,);
  75. int next=mul(now,);
  76. Downow(now,next,k);//只需要下更新
  77. if(mid>=x)
  78. return Query(sta,mid,next,x,k);
  79. else
  80. return Query(mid+,enn,next|,x,k);
  81. }
  82. int main()
  83. {
  84. int n,q,coun=;
  85. for(int i=;i<;i++)
  86. for(int j=;j<=i;j++)
  87. pos[i][j]=coun++;
  88. while(~scanf("%d",&n))
  89. {
  90. Create(,n,);
  91. scanf("%d",&q);
  92. int typ,lef,rig,k;
  93. int add;
  94. while(q--)
  95. {
  96. scanf("%d",&typ);
  97. if(typ==)
  98. {
  99. add=;
  100. scanf("%d",&lef);
  101. for(int i=; i<; i++)//查询时需要查询10棵树
  102. add+=Query(,n,,(lef+i)/(i+),pos[i][(lef-)%(i+)]);//相同大小在每棵树的位置不一样,注意
  103. add+=per[lef];
  104. printf("%d\n",add);
  105. }
  106. else
  107. {
  108. scanf("%d %d %d %d",&lef,&rig,&k,&add);//只是更新一棵树就好
  109. Update(,n,,(lef+k-)/k,(rig-lef)/k+(lef+k-)/k,pos[k-][(lef-)%k],add);//注意更新的只是输入的左右区间内的一部分
  110. }
  111. }
  112. }
  113. return ;
  114. }

HDU 4267 A Simple Problem with Integers(2012年长春网络赛A 多颗线段树+单点查询)的更多相关文章

  1. HDU 4267 A Simple Problem with Integers

    A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  2. HDU 4267 A Simple Problem with Integers(树状数组区间更新)

    A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  3. 【树状数组区间修改单点查询+分组】HDU 4267 A Simple Problem with Integers

    http://acm.hdu.edu.cn/showproblem.php?pid=4267 [思路] 树状数组的区间修改:在区间[a, b]内更新+x就在a的位置+x. 然后在b+1的位置-x 树状 ...

  4. HDU 4267 A Simple Problem with Integers --树状数组

    题意:给一个序列,操作1:给区间[a,b]中(i-a)%k==0的位置 i 的值都加上val  操作2:查询 i 位置的值 解法:树状数组记录更新值. 由 (i-a)%k == 0 得知 i%k == ...

  5. 2012年长春网络赛(hdu命题)

    为迎接9月14号hdu命题的长春网络赛 ACM弱校的弱菜,苦逼的在机房(感谢有你)呻吟几声: 1.对于本次网络赛,本校一共6名正式队员,训练靠的是完全的自主学习意识 2.对于网络赛的群殴模式,想竞争现 ...

  6. HDOJ 4267 A Simple Problem with Integers (线段树)

    题目: Problem Description Let A1, A2, ... , AN be N elements. You need to deal with two kinds of opera ...

  7. HDU 4747 Mex (2013杭州网络赛1010题,线段树)

    Mex Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submis ...

  8. HDU 3974 Assign the task(DFS序+线段树单点查询,区间修改)

    描述There is a company that has N employees(numbered from 1 to N),every employee in the company has a ...

  9. 【HDOJ】4267 A Simple Problem with Integers

    树状数组.Easy. /* 4267 */ #include <iostream> #include <string> #include <map> #includ ...

随机推荐

  1. Angular 资料大集合

    https://angular.cn/   Angular 的中文网 http://www.apjs.net/#dir1    Angular 的中文网 http://www.ngnice.com/  ...

  2. JFinal中json的使用

    之前Java开发一直使用的是经典的ssh,去年接触了jfinal,觉得jfinal的魅力非常之大,让我无法自拔,现在还深深地陷在其中. 简单的介绍一下jfinal,jfinal短小精悍,让java有了 ...

  3. 转:什么是Node.js?

    Node不是万能药!但的确能解决一些关键问题 学习Node不是一件轻松事儿,但你所收到的回报是对得起你的付出的.因为当下Web应用开发中的诸多难题唯有JavaScript才能解决. 目录 专家们的警告 ...

  4. iOS swift 给MBProgressHUD添加分类

    MBProgressHUD在开发中经常会用到,今天把MBProgressHUD的方法拓展了一下,更加方便使用 1.可以实现gif图片的展示,使用时请替换test.gif 2.可以控制是否允许交互,如果 ...

  5. 50条SQL查询技巧、查询语句示例

    学习了 1.查询“001”课程比“002”课程成绩高的所有学生的学号: 2.查询平均成绩大于60分的同学的学号和平均成绩: 3.查询所有同学的学号.姓名.选课数.总成绩: 4.查询姓“李”的老师的个数 ...

  6. python的list求和与求积

    python中,无论是对的list求和还是求积,我都给出了两种方法. 1.对list求和 1.1 s=0 for i in range(10): s+=i 1.2 s=sum(range(10)) 2 ...

  7. oracle10g卸载问题

    oracle10g卸载是一个比较麻烦的事,一般要完全卸载有以下几个步骤: 实现方法:1.开始->设置->控制面板->管理工具->服务停止所有Oracle服务:2.开始-> ...

  8. vue实践---vue不依赖外部资源实现简单多语

    vue使用多语,最常见的就是 vue-i18n, 但是如果开发中的多语很少,比如就不到10个多语,这样就没必要引入vue-i18n了, 引入了反正导致代码体积大了,这时候单纯用vue实现多语就是比较好 ...

  9. 在Hierarchy面板隐藏物体

    PlantObjPreview.hideFlags = HideFlags.HideInHierarchy;

  10. JUNIT单元测试时统计代码的覆盖率工具eclemma安装

    EclEmma是Eclipse里的一个插件,安装简单,覆盖率显示直观.安装EclEmma.打开Eclipse,点击Help → Software Updates → Find and Install, ...