两种做法。

第一种:标记区间最大值和最小值,若区间最小值>=P,则本区间+2c,若区间最大值<P,则本区间+c。非常简单的区间更新。

最后发一点牢骚:最后query查一遍就行,我这个2B竟然写了个for循环每个点查了一遍orz……然后比赛的时候就一直TLE还查不出原因……感觉线段树对我就像个诅咒一样,每场必不出,不管是多么简单的线段树,都会错在千奇百怪的地方……说到底也不过是对线段树掌握的不扎实罢了,sigh……以后要多加练习!

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cstdlib>
  4.  
  5. #define lson l, m, rt << 1
  6. #define rson m + 1, r, rt << 1 | 1
  7. #define lc rt << 1
  8. #define rc rt << 1 | 1
  9.  
  10. using namespace std;
  11.  
  12. const int MAXN = ;
  13.  
  14. int N, M, P;
  15. int sum[MAXN << ];
  16. int maxi[MAXN << ];
  17. int mini[MAXN << ];
  18. int lazy[MAXN << ];
  19.  
  20. void build( int l, int r, int rt )
  21. {
  22. sum[rt] = lazy[rt] = ;
  23. maxi[rt] = ;
  24. mini[rt] = ;
  25. if ( l == r ) return;
  26. int m = ( l + r ) >> ;
  27. build( lson );
  28. build( rson );
  29. return;
  30. }
  31.  
  32. inline void PushDown( int rt, int m )
  33. {
  34. if ( lazy[rt] )
  35. {
  36. lazy[lc] += lazy[rt];
  37. lazy[rc] += lazy[rt];
  38. sum[lc] += lazy[rt]*(m - (m >> ) );
  39. sum[rc] += lazy[rt]*(m >> );
  40. maxi[lc] += lazy[rt], mini[lc] += lazy[rt];
  41. maxi[rc] += lazy[rt], mini[rc] += lazy[rt];
  42. lazy[rt] = ;
  43. }
  44. return;
  45. }
  46.  
  47. inline void PushUp( int rt )
  48. {
  49. sum[rt] = sum[lc] + sum[rc];
  50. maxi[rt] = maxi[lc] > maxi[rc] ? maxi[lc] : maxi[rc];
  51. mini[rt] = mini[lc] < mini[rc] ? mini[lc] : mini[rc];
  52. return;
  53. }
  54.  
  55. inline void update( int L, int R, int val, int l, int r, int rt )
  56. {
  57. if ( L <= l && r <= R )
  58. {
  59. if ( maxi[rt] < P )
  60. {
  61. lazy[rt] += val;
  62. sum[rt] += val*(r - l + );
  63. maxi[rt] += val;
  64. mini[rt] += val;
  65. return;
  66. }
  67. else if ( mini[rt] >= P )
  68. {
  69. lazy[rt] += *val;
  70. sum[rt] += *val*(r - l + );
  71. maxi[rt] += *val;
  72. mini[rt] += *val;
  73. return;
  74. }
  75. }
  76. if ( l == r ) return;
  77. PushDown( rt, r - l + );
  78.  
  79. int m = ( l + r ) >> ;
  80. if ( L <= m ) update( L, R, val, lson );
  81. if ( R > m ) update( L, R, val, rson );
  82. PushUp( rt );
  83.  
  84. return;
  85. }
  86.  
  87. bool first;
  88.  
  89. void query( int l, int r, int rt )
  90. {
  91. if ( l == r )
  92. {
  93. if ( first ) putchar(' ');
  94. first = true;
  95. printf( "%d", sum[rt] );
  96. return;
  97. }
  98. PushDown( rt, r - l + );
  99. int m = ( l + r ) >> ;
  100. query( lson );
  101. query( rson );
  102. return;
  103. }
  104.  
  105. int main()
  106. {
  107. while ( scanf( "%d%d%d", &N, &M, &P ) == )
  108. {
  109. build( , N, );
  110. for ( int i = ; i < M; ++i )
  111. {
  112. int a, b, c;
  113. scanf( "%d%d%d", &a, &b, &c );
  114. update( a, b, c, , N, );
  115. }
  116. first = false;
  117. query( , N, );
  118. puts("");
  119. }
  120. return ;
  121. }

第二种做法:线段树的特殊懒惰标记,方法跟 HDU 3954 一样。代码稍微改改就行。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cstdlib>
  4. #include <algorithm>
  5.  
  6. #define lson l, m, rt << 1
  7. #define rson m + 1, r, rt << 1 | 1
  8. #define lc rt << 1
  9. #define rc rt << 1 | 1
  10.  
  11. using namespace std;
  12.  
  13. const int MAXN = ;
  14. const int INF = << ;
  15.  
  16. struct node
  17. {
  18. int exp, level;
  19. int min_dis;
  20. int flag;
  21. };
  22.  
  23. int N, M, P;
  24. int K;
  25. node Tr[ MAXN << ];
  26. int sum[];
  27.  
  28. void build( int l, int r, int rt )
  29. {
  30. Tr[rt].exp = Tr[rt].flag = ;
  31. Tr[rt].level = ;
  32. Tr[rt].min_dis = sum[];
  33. if ( l == r ) return ;
  34. int m = ( l + r ) >> ;
  35. build( lson );
  36. build( rson );
  37. return;
  38. }
  39.  
  40. void PushDown( int rt )
  41. {
  42. if ( Tr[rt].flag )
  43. {
  44. Tr[lc].exp += Tr[rt].flag * Tr[lc].level;
  45. Tr[lc].min_dis -= Tr[rt].flag;
  46. Tr[lc].flag += Tr[rt].flag;
  47.  
  48. Tr[rc].exp += Tr[rt].flag * Tr[rc].level;
  49. Tr[rc].min_dis -= Tr[rt].flag;
  50. Tr[rc].flag += Tr[rt].flag;
  51.  
  52. Tr[rt].flag = ;
  53. }
  54. return;
  55. }
  56.  
  57. void PushUp( int rt )
  58. {
  59. Tr[rt].level = max( Tr[lc].level, Tr[rc].level );
  60. Tr[rt].exp = max( Tr[lc].exp, Tr[rc].exp );
  61. Tr[rt].min_dis = min( Tr[lc].min_dis, Tr[rc].min_dis );
  62. return;
  63. }
  64.  
  65. void Update( int L, int R, int v, int l, int r, int rt )
  66. {
  67. if ( l == r )
  68. {
  69. Tr[rt].exp += Tr[rt].level * v;
  70. while ( Tr[rt].exp >= sum[ Tr[rt].level ] )
  71. ++Tr[rt].level;
  72. Tr[rt].min_dis = ( sum[ Tr[rt].level ] - Tr[rt].exp ) / Tr[rt].level;
  73. if( ( sum[ Tr[rt].level ] - Tr[rt].exp ) % Tr[rt].level ) ++Tr[rt].min_dis;
  74. return;
  75. }
  76. int m = ( l + r ) >> ;
  77.  
  78. if ( L == l && r == R )
  79. {
  80. if ( v >= Tr[rt].min_dis )
  81. {
  82. PushDown(rt);
  83. if ( R <= m ) Update( L, R, v, lson );
  84. else if ( L > m ) Update( L, R, v, rson );
  85. else
  86. {
  87. Update( L, m, v, lson );
  88. Update( m + , R, v, rson );
  89. }
  90. PushUp(rt);
  91. }
  92. else
  93. {
  94. Tr[rt].exp += Tr[rt].level * v;
  95. Tr[rt].min_dis -= v;
  96. Tr[rt].flag += v;
  97. }
  98. return;
  99. }
  100.  
  101. PushDown(rt);
  102.  
  103. if ( R <= m ) Update( L, R, v, lson );
  104. else if ( L > m ) Update( L, R, v, rson );
  105. else
  106. {
  107. Update( L, m, v, lson );
  108. Update( m + , R, v, rson );
  109. }
  110.  
  111. PushUp(rt);
  112.  
  113. return;
  114. }
  115.  
  116. bool first;
  117.  
  118. void Query( int l, int r, int rt )
  119. {
  120. if ( l == r )
  121. {
  122. if ( first ) putchar(' ');
  123. first = true;
  124. printf( "%d", Tr[rt].exp );
  125. return;
  126. }
  127. PushDown(rt);
  128. int m = ( l + r ) >> ;
  129. Query( lson );
  130. Query( rson );
  131. return;
  132. }
  133.  
  134. int main()
  135. {
  136. K = ;
  137. while ( scanf( "%d%d%d", &N, &M, &P ) == )
  138. {
  139. sum[] = P;
  140. sum[] = INF;
  141.  
  142. build( , N, );
  143. while ( M-- )
  144. {
  145. int a, b, c;
  146. scanf( "%d%d%d", &a, &b, &c );
  147. Update( a, b, c, , N, );
  148. }
  149. first = false;
  150. Query( , N, );
  151. puts("");
  152. }
  153. return ;
  154. }

HDU 4107 Gangster(线段树 特殊懒惰标记)的更多相关文章

  1. HDU 3397 线段树 双懒惰标记

    这个是去年遗留历史问题,之前思路混乱,搞了好多发都是WA,就没做了 自从上次做了大白书上那个双重懒惰标记的题目,做这个就思路很清晰了 跟上次大白上那个差不多,这个也是有一个sets标记,代表这个区间全 ...

  2. hdu 1828 Picture(线段树 || 普通hash标记)

    http://acm.hdu.edu.cn/showproblem.php?pid=1828 Picture Time Limit: 6000/2000 MS (Java/Others)    Mem ...

  3. poj3468 线段树的懒惰标记

    题目链接:poj3468 题意:给定一段数组,有两种操作,一种是给某段区间加c,另一种是查询一段区间的和 思路:暴力的方法是每次都给这段区间的点加c,查询也遍历一遍区间,复杂度是n*n,肯定过不去,另 ...

  4. HDU 3954 Level up (线段树特殊懒惰标记)

    http://blog.csdn.net/acm_cxlove/article/details/7548087 感觉最巧的是定义了min_dis……将区间内有无英雄升级分开处理 #include &l ...

  5. hdu 4031 attack 线段树区间更新

    Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Subm ...

  6. hdu 4288 离线线段树+间隔求和

    Coder Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  7. hdu 3016 dp+线段树

    Man Down Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  8. Transformation HDU - 4578(线段树——懒惰标记的妙用)

    Yuanfang is puzzled with the question below: There are n integers, a 1, a 2, …, a n. The initial val ...

  9. hdu 4107 Gangster(线段树,时间卡得很严)

    这道题目的数据卡得好厉害. 题目明显是考察线段树延迟标记的,但是因为要考虑到p的值,这种延迟是有条件的:在该节点下所有的数据对于p都应该位于p的同一侧.要么都比p大,要么都比p小. 开始的时候我用一个 ...

随机推荐

  1. layui table 用法

    1.使用模板列 改变样式 获取嵌套数据{ field: '', width: '12%', title: '响应状态', sort: true, templet: function (d) { if ...

  2. linux:eth网卡对应的物理网口判断

    可以利用ethtool命令 #ethtool -p eth0 执行上述命令则相应的物理网口会闪烁,则可以判断对应的物理网口 注:应在不插网线的情况下测试

  3. phpmailer类的再封装

    email <?php use PHPMailer\PHPMailer\PHPMailer; class Email { const SMTPDebug = 2; const HOST = 's ...

  4. 连接mysql 报错 Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

    网上找不到  朋友说是因为非正常关机导致,mysql.server start 运行报错 ERROR! The server quit without updating PID file(): 解决办 ...

  5. 细说 unicode 、utf-8 、utf-16、ascii 、gbk 、gb2312

    一.计算机的由来 很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物.他们看到8个开关状态是好的,于是他们把这称为”字节“.再后来,他们又做了一些可以处理这些 ...

  6. google云函数实现BigQuery数据操作

    Google Cloud Function操作BigQuery数据库. 1.部署云函数时在配置文件中(package.json)添加一项 "@google-cloud/bigquery&qu ...

  7. manjaro安装teamviewer后无法打开

    点桌面快捷方式一闪而过 命令行运行提示 $ teamviewer /opt/teamviewer/tv_bin/script/tvw_exec:行7: /opt/teamviewer/logfiles ...

  8. Android面试收集录 Android布局

    1.请说出Android中的五种布局,并介绍作用? FrameLayout(堆栈布局),层叠方式显示,类似于PhotoShop上的层叠图层. LinearLayout(线性布局),将视图以水平或者垂直 ...

  9. Android开发——View滑动冲突解决方案

    0. 前言   我们在Android开发--事件分发机制详解中深入学习了事件分发机制,为我们解决Android开发中的滑动冲突问题做了初步准备.针对滑动冲突这里给出两种解决方案:外部拦截法和内部拦截法 ...

  10. 「微信小程序免费辅导教程」26,基础内容组件rich-text体验