题目描述

教主最近学会了一种神奇的魔法,能够使人长高。于是他准备演示给XMYZ信息组每个英雄看。于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1、2、……、N。

每个人的身高一开始都是不超过1000的正整数。教主的魔法每次可以把闭区间[L, R](1≤L≤R≤N)内的英雄的身高全部加上一个整数W。(虽然L=R时并不符合区间的书写规范,但我们可以认为是单独增加第L(R)个英雄的身高)

CYZ、光哥和ZJQ等人不信教主的邪,于是他们有时候会问WD闭区间 [L, R] 内有多少英雄身高大于等于C,以验证教主的魔法是否真的有效。

WD巨懒,于是他把这个回答的任务交给了你。

输入输出格式

输入格式:

第1行为两个整数N、Q。Q为问题数与教主的施法数总和。

第2行有N个正整数,第i个数代表第i个英雄的身高。

第3到第Q+2行每行有一个操作:

(1) 若第一个字母为“M”,则紧接着有三个数字L、R、W。表示对闭区间 [L, R] 内所有英雄的身高加上W。

(2) 若第一个字母为“A”,则紧接着有三个数字L、R、C。询问闭区间 [L, R] 内有多少英雄的身高大于等于C。

输出格式:

对每个“A”询问输出一行,仅含一个整数,表示闭区间 [L, R] 内身高大于等于C的英雄数。

输入输出样例

输入样例#1:

  1. 5 3
  2.  
  3. 1 2 3 4 5
  4.  
  5. A 1 5 4
  6.  
  7. M 3 5 1
  8.  
  9. A 1 5 4
输出样例#1:

  1. 2
  2. 3

说明

【输入输出样例说明】

原先5个英雄身高为1、2、3、4、5,此时[1, 5]间有2个英雄的身高大于等于4。教主施法后变为1、2、4、5、6,此时[1, 5]间有3个英雄的身高大于等于4。

【数据范围】

对30%的数据,N≤1000,Q≤1000。

对100%的数据,N≤1000000,Q≤3000,1≤W≤1000,1≤C≤1,000,000,000。

分块大法 。

不明白为什么跑的快 。。(本人蒟蒻)

屠龙宝刀点击就送

  1. #include <algorithm>
  2. #include <ctype.h>
  3. #include <cstdio>
  4. #include <cmath>
  5. #define N 1005
  6.  
  7. using namespace std;
  8. void read(int &x)
  9. {
  10. x=;
  11. bool f=;
  12. char ch=getchar();
  13. while(!isdigit(ch))
  14. {
  15. if(ch=='-') f=;
  16. ch=getchar();
  17. }
  18. while(isdigit(ch))
  19. {
  20. x=x*+ch-'';
  21. ch=getchar();
  22. }
  23. x=f?(~x)+:x;
  24. }
  25. int min(int a,int b){return a>b?b:a;}
  26. int tag[N],C,n,m,h[N],a[N*N],b[N*N],st[N],en[N],cnt;
  27. void violence_c(int k,int l,int r,int v)
  28. {
  29. for(int i=st[k];i<=en[k];i++)
  30. {
  31. b[i]=a[i]+tag[k];
  32. if(l<=i&&i<=r) b[i]+=v;
  33. }
  34. sort(b+st[k],b+en[k]+);
  35. }
  36. void update(int l,int r,int v)
  37. {
  38. for(int i=;i<=cnt;i++)
  39. {
  40. if(st[i]>=l&&en[i]<=r) tag[i]+=v;
  41. else if(st[i]<=l&&en[i]>=l) violence_c(i,l,en[i],v);
  42. else if(st[i]<=r&&en[i]>=r) violence_c(i,st[i],r,v);
  43. }
  44. }
  45. int ef(int k,int v)
  46. {
  47. int l=st[k],r=en[k],ans=0x7fffffff;
  48. while(l<=r)
  49. {
  50. int mid=(l+r)>>;
  51. if(b[mid]+tag[k]>=v)
  52. ans=min(ans,mid),r=mid-;
  53. else l=mid+;
  54. }
  55. if(ans==0x7fffffff) return ;
  56. else return en[k]-ans+;
  57. }
  58. int violence_q(int k,int l,int r,int z)
  59. {
  60. int sum=;
  61. for(int i=l;i<=r;i++) if(a[i]+tag[k]>=z) sum++;
  62. return sum;
  63. }
  64. int query(int l,int r,int z)
  65. {
  66. int ans=;
  67. for(int i=;i<=cnt;i++)
  68. {
  69. if(st[i]>=l&&en[i]<=r) ans+=ef(i,z);
  70. else if(st[i]<=l&&en[i]>=l) ans+=violence_q(i,l,en[i],z);
  71. else if(st[i]<=r&&en[i]>=r) ans+=violence_q(i,st[i],r,z);
  72. }
  73. return ans;
  74. }
  75. int main()
  76. {
  77. scanf("%d%d",&n,&m);
  78. C=sqrt(n);
  79. for(int i=;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];
  80. for(int i=;i<=n;i+=C)
  81. {
  82. st[++cnt]=i;
  83. en[cnt]=min(n,i+C-);
  84. sort(b+st[cnt],b+en[cnt]+);
  85. }
  86. char str[];
  87. for(int x,y,z;m--;)
  88. {
  89. scanf("%s%d%d%d",str+,&x,&y,&z);
  90. switch(str[])
  91. {
  92. case 'A':
  93. {
  94. printf("%d\n",query(x,y,z));
  95. break;
  96. }
  97. case 'M':
  98. {
  99. update(x,y,z);
  100. break;
  101. }
  102. }
  103. }
  104. return ;
  105. }

洛谷 P2801 教主的魔法的更多相关文章

  1. 洛谷 P2801 教主的魔法 解题报告

    P2801 教主的魔法 题目描述 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.--.N. ...

  2. 洛谷——P2801 教主的魔法(线段树or分块)

    P2801 教主的魔法 (1) 若第一个字母为“M”,则紧接着有三个数字L.R.W.表示对闭区间 [L, R] 内所有英雄的身高加上W. (2) 若第一个字母为“A”,则紧接着有三个数字L.R.C.询 ...

  3. 洛谷P2801 教主的魔法 [分块,二分答案]

    题目传送门 教主的魔法 题目描述 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. ...

  4. BZOJ——3343: 教主的魔法 || 洛谷—— P2801 教主的魔法

    http://www.lydsy.com/JudgeOnline/problem.php?id=3343  ||  https://www.luogu.org/problem/show?pid=280 ...

  5. 洛谷P2801 教主的魔法 分块

    正解:分块 解题报告: 哇之前的坑还没填完就又写新博客? 不管不管,之前欠的两三篇题解大概圣诞节之前会再仔细想想然后重新写下题解趴,确实还挺难的感觉没有很好的理解呢QAQ还是太囫囵吞枣不求甚解了,这样 ...

  6. [洛谷P2801]教主的魔法

    题目大意:有$n$个数,$q$个操作.两种操作: $M\;l\;r\;w:$把$[l,r]$所有数加上$w$ $A\;l\;r\;c:$查询$[l,r]$内大于等于$c$的元素的个数. 题解:分块,对 ...

  7. 洛谷 P2801 教主的魔法 题解

    题面 刚看到这道题的时候用了个树状数组优化前缀和差分的常数优化竟然AC了?(这数据也太水了吧~) 本人做的第一道分块题,调试了好久好久,最后竟然没想到二分上还会出错!(一定要注意)仅此纪念: #inc ...

  8. P2801 教主的魔法(分块)

    P2801 教主的魔法 区间加法,区间查询 显然就是分块辣 维护一个按块排好序的数组. 每次修改依然是整块打标记,零散块暴力.蓝后对零散块重新排序. 询问时整块二分,零散块暴力就好辣 注意细节挺多和边 ...

  9. P2801 教主的魔法 (线段树)

    题目 P2801 教主的魔法 解析 成天做水题 线段树,第一问区间加很简单 第二问可以维护一个区间最大值和一个区间最小值,若C小于等于区间最小值,就加上区间长度,若C大于区间最大值,就加0 ps:求教 ...

随机推荐

  1. ubuntu中查看已安装软件包的方法

    ubuntu中查看已安装软件包的方法: 方法一:在新立得软件包管理器中,打到已安装,便可以看看有多少包被安装. 如果想把这些包的信息复制到一文件里,可用下面的方法. 方法二:在终端输入 sudo dp ...

  2. 汉诺塔算法c++源代码(递归与非递归)[转]

     算法介绍: 其实算法非常简单,当盘子的个数为n时,移动的次数应等于2^n - 1(有兴趣的可以自己证明试试看).后来一位美国学者发现一种出人意料的简单方法,只要轮流进行两步操作就可以了.首先把三根柱 ...

  3. Nyquist–Shannon sampling theorem 采样定理

    Nyquist–Shannon sampling theorem - Wikipedia https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_s ...

  4. GrideView(三)---编辑功能实现

    GrideView(三)---编辑 法一.(优势:操作数据更加灵活:劣势: 书写较多代码,开发效率低) 通过编辑列---添加超链接(HyperlinkField)字段 ,来跳转页面实现编辑操作: 步骤 ...

  5. Java简单的加密解密算法,使用异或运算

    package cn.std.util; import java.nio.charset.Charset; public class DeEnCode { private static final S ...

  6. [Usaco2017 Dec] A Pie for a Pie

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=5140 [算法] 最短路 时间复杂度 : O(N^2) [代码] #include&l ...

  7. 在linq语言中,不能准确按拼音排序(转)

    在项目中,利用OrderBy/OrderByDescending, ThenBy/ThenByDescending这4个方法排序时,发现了这样的问题:在本机测试,能正确按拼音排序:但是放上服务器是,就 ...

  8. NDK相关收藏【转】

    http://blog.csdn.net/column/details/anidea-ndk.html   [转] 作者:conowen@大钟

  9. layui 添加第三方插件

    关于 layui 添加第三方 JS 库 在写公司项目时,需要将第三方 JS 库整合到 layui 中,具体操作如下: 示例:https://www.jianshu.com/p/7a182e8bff10 ...

  10. [Usaco2008 Feb]Eating Together麻烦的聚餐

    Description 为了避免餐厅过分拥挤,FJ要求奶牛们分3批就餐.每天晚饭前,奶牛们都会在餐厅前排队入内,按FJ的设想所有第3批就餐的奶牛排在队尾,队伍的前端由设定为第1批就餐的奶牛占据,中间的 ...