因为询问比较少,所以我们可以将n个数分成sqrt(n)个块,每个块用一颗bst存一下,然后对于修改l,r,我们将l,r区间中整块的直接在bst上打一个标签,对于不是整块的我们直接暴力修改,对于询问l,r,仍然是整块的直接在bst中求大于c的个数(考虑标签),然后不是整块的部分暴力扫一遍更新答案。

  我写的sbt,可能是sbt常数比较大什么的,tle了,其实对于每一个块我们可以快排保存,然后询问的时候二分就好了。然后对于不是整块的修改和询问可以直接改完之后再快排,这样常数小了很多。

  懒得改了,贴sbt的吧。

  1. /**************************************************************
  2. Problem: 3343
  3. User: BLADEVIL
  4. Language: C++
  5. Result: Accepted
  6. Time:9976 ms
  7. Memory:47712 kb
  8. ****************************************************************/
  9.  
  10. #include <cstdio>
  11. #include <algorithm>
  12. #include <cstring>
  13. #include <cmath>
  14. using namespace std ;
  15. #define MAXN 2000100
  16. #define MAXB 1100
  17. #define L( t ) Left[ t ]
  18. #define R( t ) Right[ t ]
  19. #define K( t ) Key[ t ]
  20. #define S( t ) Size[ t ]
  21. #define update( t )S( t )=S(L( t ))+S(R( t ))+1
  22. #define check( ch )( ch >='0'&& ch <='9')
  23. void getint(int&t ){
  24. int ch ;for( ch =getchar( );!check( ch ); ch =getchar( ));
  25. t = ch -'';
  26. for( ch =getchar( );check( ch ); ch =getchar( )) t *=, t += ch -'';
  27. }
  28. int Left[ MAXN ], Right[ MAXN ], Key[ MAXN ], Size[ MAXN ], V =;
  29. void left(int&t ){
  30. int k =R( t );
  31. R( t )=L( k );update( t );
  32. L( k )= t ;update( k );
  33. t = k ;
  34. }
  35. void right(int&t ){
  36. int k =L( t );
  37. L( t )=R( k );update( t );
  38. R( k )= t ;update( k );
  39. t = k ;
  40. }
  41. void maintain(int&t ){
  42. if(S(L(L( t )))>S(R( t ))){
  43. right( t );
  44. maintain(R( t ));maintain( t );
  45. return;
  46. }
  47. if(S(R(R( t )))>S(L( t ))){
  48. left( t );
  49. maintain(L( t ));maintain( t );
  50. return;
  51. }
  52. if(S(R(L( t )))>S(R( t ))){
  53. left(L( t ));right( t );
  54. maintain(L( t )),maintain(R( t ));
  55. maintain( t );
  56. return;
  57. }
  58. if(S(L(R( t )))>S(L( t ))){
  59. right(R( t ));left( t );
  60. maintain(L( t )),maintain(R( t ));
  61. maintain( t );
  62. return;
  63. }
  64. }
  65. void Insert(int k ,int&t ){
  66. if(! t ){
  67. t =++ V ;
  68. L( t )=R( t )=;
  69. S( t )=,K( t )= k ;
  70. return;
  71. }
  72. S( t )++;
  73. Insert( k , k <K( t )?L( t ):R( t ));
  74. maintain( t );
  75. }
  76.  
  77. void Delete(int k ,int&t ){
  78. if( k ==K( t )){
  79. if(!L( t )){
  80. t =R( t );return;
  81. }
  82. if(!R( t )){
  83. t =L( t );return;
  84. }
  85. right( t );Delete( k ,R( t ));
  86. }else Delete( k , k <K( t )?L( t ):R( t ));
  87. update( t );
  88. maintain( t );
  89. }
  90.  
  91. int Rank(int k ,int t ){
  92. if(! t )return ;
  93. if( k <=K( t ))return S(R( t ))++Rank( k ,L( t ));
  94. return Rank( k ,R( t ));
  95. }
  96. int a[ MAXN ], block[ MAXN ], head[ MAXB ], tail[ MAXB ], roof[ MAXB ], C[ MAXB ];
  97. int n , m , b =;
  98. int Query(int l ,int r ,int c ){
  99. if( block[ l ]== block[ r ]){
  100. int x = block[ l ];
  101. if( head[ x ]== l && tail[ x ]== r )return Rank( c - C[ x ], roof[ x ]);
  102. int cnt =;
  103. for(int i = l ; i <= r ; i ++)if( a[ i ]>= c - C[ x ]) cnt ++;
  104. return cnt ;
  105. }
  106. int cnt =Query( l , tail[ block[ l ]], c )+Query( head[ block[ r ]], r , c );
  107. for(int i = block[ l ]+; i < block[ r ]; i ++){
  108. cnt +=Rank( c - C[ i ], roof[ i ]);
  109. }
  110. return cnt ;
  111. }
  112.  
  113. void Change(int l ,int r ,int c ){
  114. if( block[ l ]== block[ r ]){
  115. int x = block[ l ];
  116. if( l == head[ x ]&& r == tail[ x ]){
  117. C[ x ]+= c ;
  118. return;
  119. }
  120. for(int i = l ; i <= r ; i ++){
  121. Delete( a[ i ], roof[ x ]);
  122. a[ i ]+= c ;
  123. Insert( a[ i ], roof[ x ]);
  124. }
  125. return;
  126. }
  127. Change( l , tail[ block[ l ]], c ),Change( head[ block[ r ]], r , c );
  128. for(int i = block[ l ]+; i < block[ r ]; i ++){
  129. C[ i ]+= c ;
  130. }
  131. }
  132.  
  133. int main( ){
  134. memset( roof ,,sizeof( roof ));
  135. memset( C ,,sizeof( C ));
  136. L()=R()=S()=;
  137. getint( n ),getint( m );
  138. for(int i =; i ++< n ;)getint( a[ i ]);
  139. b =int(sqrt( n ));
  140. for(int i =; i ++< b ;){
  141. for(int j =( i -)* b ; j ++< i * b ;){
  142. block[ j ]= i ;
  143. Insert( a[ j ], roof[ i ]);
  144. }
  145. head[ i ]=( i -)* b +, tail[ i ]= i * b ;
  146. }
  147. if( b * b < n ){
  148. head[ b +]= b * b +, tail[ b +]= n ;
  149. for(int i = b * b ; i ++< n ;){
  150. block[ i ]= b +;
  151. Insert( a[ i ], roof[ b +]);
  152. }
  153. }
  154. while( m --){
  155. int ch , l , r , c ;
  156. for( ch =getchar( );!( ch >='A'&& ch <='Z'); ch =getchar( ));
  157. if( ch =='M'){
  158. getint( l ),getint( r ),getint( c );
  159. Change( l , r , c );
  160. }else{
  161. getint( l ),getint( r ),getint( c );
  162. printf("%d\n",Query( l , r , c ));
  163. }
  164. }
  165. return ;
  166. }

bzoj 3343 分块的更多相关文章

  1. BZOJ 3343: 教主的魔法(分块+二分查找)

    BZOJ 3343: 教主的魔法(分块+二分查找) 3343: 教主的魔法 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1172  Solved:  ...

  2. BZOJ 3343: 教主的魔法 [分块]【学习笔记】

    3343: 教主的魔法 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1172  Solved: 526[Submit][Status][Discus ...

  3. 【BZOJ 3343 】 分块

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

  4. 分块+二分 BZOJ 3343

    3343: 教主的魔法 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1312  Solved: 585[Submit][Status][Discus ...

  5. BZOJ 3343:教主的魔法(分块)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3343 [题目大意] 给出一个数列,有区间加法操作,询问区间大于等于c的数字个数 [题解 ...

  6. Bzoj 3343: 教主的魔法(分块+二分答案)

    3343: 教主的魔法 Time Limit: 10 Sec Memory Limit: 256 MB Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息 ...

  7. Bzoj 3343: 教主的魔法 分块,二分

    3343: 教主的魔法 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 821  Solved: 364[Submit][Status][Discuss ...

  8. BZOJ 3343 教主的魔法(分块)

    题意: 有一个1e6的数组,t次操作:将[l,r]内的值增加w,或者查询[l,r]内的值大于等于add的 思路: 分块,块大小为sqrt(n),每次只需要暴力头尾两块,中间的整块打标记, 对于查询查操 ...

  9. bzoj 3343 教主的魔法 分块

    修改直接对整块打标记,两边暴力. 查询需要保证每个整块有序,所以在修改时排序就好啦 #include<cstdio> #include<cstring> #include< ...

随机推荐

  1. thrift多平台安装

    thrift支持多语言的RPC,一直都想深入学习了解thrift,最近有空,就上网查了些资料,学习了一下,对它的使用有了一些了解.本篇是写thrift的安装,使用方法会另起一篇来写. 本文使用thri ...

  2. Ansys Workbench热流固耦合仿真配置

    1.Fluent-Thermal-Structural瞬态分析 此模块连接在fluent已实现流体和固体的热流耦合,传递至thermal实际上只是将流体表面温度作为热载荷施加在固体的液体通道表面,极大 ...

  3. Perfmon - Windows 自带系统监控工具

    一. 简述 可以用于监视CPU使用率.内存使用率.硬盘读写速度.网络速度等. Perfmon提供了图表化的系统性能实时监视器.性能日志和警报管理,系统的性能日志可定义为二进制文件.文本文件.SQLSE ...

  4. VBA 练习-从两个库中调用数据到活动表中

    练习VBA Sub 填报入库单() Dim basedb As String, cpdb As String, wb As Workbook, ws As Worksheet, curWs As Wo ...

  5. Socket_FTP

    1. md5加密回顾: import hashlib m=hashlib.md5() #创建md5对象 m.update(b'abcd') #生成加密串 m.update(b'efg') print( ...

  6. Android ListView 中加入CheckBox/RadioButton 选择状态保持、全选、反选实现

    最近在一个项目中,需要在ListView的item中加入CheckBox,但是遇到的一个问题是上下滑动的时候如果有选择了的CheckBox,就会出现选择项错误的问题,下面将个人的解决方法总结如下;先说 ...

  7. BZOJ1047:[HAOI2007]理想的正方形——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=1047 https://www.luogu.org/problemnew/show/P2216#sub ...

  8. React Render Callback Pattern(渲染回调模式)

    React Render Callback Pattern,渲染回调模式,其实是将this.props.children当做函数来调用. 例如: 要根据user参数确定渲染Loading还是Profi ...

  9. Android源码4.4.4_r1下载和编译

    系统:ubuntu 16.04.2 TLS 1.源码下载: sudo apt-get install curl curl https://storage.googleapis.com/git-repo ...

  10. angularJS批量删除 品优购删除品牌(通用复选框批量选中删除解决思路)

    思路: 一步:在点击复选框时维护变量数组 在js中定义一个数组变量, 给复选框添加点击动作, 在动作中判断当前复选框是否为选中状态(即点击后复选框的是否选中状态), 若为选中状态,则向数组中添加选中的 ...