Gorgeous Sequence

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 349    Accepted Submission(s): 57

Problem Description
There is a sequence a of length n. We use ai to denote the i-th element in this sequence. You should do the following three types of operations to this sequence.

0 x y t: For every x≤i≤y, we use min(ai,t) to replace the original ai's value.
1 x y: Print the maximum value of ai that x≤i≤y.
2 x y: Print the sum of ai that x≤i≤y.

 
Input
The first line of the input is a single integer T, indicating the number of testcases.
The first line contains two integers n and m denoting the length of the sequence and the number of operations.
The second line contains n separated integers a1,…,an (∀1≤i≤n,0≤ai<231).

Each of the following m lines represents one operation (1≤x≤y≤n,0≤t<231).

It is guaranteed that T=100, ∑n≤1000000, ∑m≤1000000.

 
Output
For every operation of type 1 or 2, print one line containing the answer to the corresponding query.
 
Sample Input
1
5 5
1 2 3 4 5
1 1 5
2 1 5
0 3 5 3
1 1 5
2 1 5
 
Sample Output
5
15
3
12

Hint

Please use efficient IO method

 
Source
 
解题:线段树,对着标程写的,还是没搞清到底是怎么回事
 
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long LL;
  4. const int maxn = ;
  5. struct node {
  6. int cover,s,tag,maxtag,maxv;
  7. LL sum;
  8. } tree[maxn<<];
  9. node put(node c,int t) {
  10. if(!t) return c;
  11. if(c.cover != c.s) c.maxv = t;
  12. c.maxtag = t;
  13. c.sum += (LL)t*(c.s - c.cover);
  14. c.cover = c.s;
  15. return c;
  16. }
  17. node calc(const node &a,const node &b,int t) {
  18. node c;
  19. c.tag = t;
  20. c.s = a.s + b.s;
  21. c.sum = a.sum + b.sum;
  22. c.cover = a.cover + b.cover;
  23. c.maxv = max(a.maxv,b.maxv);
  24. c.maxtag = max(a.maxtag,b.maxtag);
  25. return put(c,t);
  26. }
  27. int tmp,n,m;
  28. void build(int L,int R,int v) {
  29. tree[v].tag = ;
  30. tree[v].s = R - L + ;
  31. if(L == R) {
  32. scanf("%d",&tmp);
  33. tree[v].sum = tree[v].tag = tree[v].maxtag = tree[v].maxv = tmp;
  34. tree[v].cover = ;
  35. return;
  36. }
  37. int mid = (L + R)>>;
  38. build(L,mid,v<<);
  39. build(mid+,R,v<<|);
  40. tree[v] = calc(tree[v<<],tree[v<<|],);
  41. }
  42. node query(int L,int R,int lt,int rt,int v) {
  43. if(lt <= L && rt >= R) return tree[v];
  44. int mid = (L + R)>>;
  45. if(rt <= mid) return put(query(L,mid,lt,rt,v<<),tree[v].tag);
  46. if(lt > mid) return put(query(mid+,R,lt,rt,v<<|),tree[v].tag);
  47. return calc(query(L,mid,lt,rt,v<<),query(mid+,R,lt,rt,v<<|),tree[v].tag);
  48. }
  49. void cleartag(int v,int t) {
  50. if(tree[v].maxtag < t) return;
  51. if(tree[v].tag >= t) tree[v].tag = ;
  52. if(tree[v].s > ) {
  53. cleartag(v<<,t);
  54. cleartag(v<<|,t);
  55. }
  56. if(tree[v].s == ) {
  57. tree[v].sum = tree[v].maxtag = tree[v].maxv = tree[v].tag;
  58. tree[v].cover = (tree[v].tag > );
  59. } else tree[v] = calc(tree[v<<],tree[v<<|],tree[v].tag);
  60. }
  61. void update(int L,int R,int lt,int rt,int t,int v) {
  62. if(tree[v].tag && tree[v].tag <= t) return;
  63. if(lt <= L && rt >= R) {
  64. cleartag(v,t);
  65. tree[v].tag = t;
  66. if(L == R) {
  67. tree[v].sum = tree[v].tag = tree[v].maxv = tree[v].maxtag = t;
  68. tree[v].cover = (tree[v].tag > );
  69. } else tree[v] = calc(tree[v<<],tree[v<<|],t);
  70. } else {
  71. int mid = (L + R)>>;
  72. if(rt <= mid) update(L,mid,lt,rt,t,v<<);
  73. else if(lt > mid) update(mid+,R,lt,rt,t,v<<|);
  74. else {
  75. update(L,mid,lt,rt,t,v<<);
  76. update(mid+,R,lt,rt,t,v<<|);
  77. }
  78. tree[v] = calc(tree[v<<],tree[v<<|],tree[v].tag);
  79. }
  80. }
  81. int main() {
  82. int kase,op,x,y,t;
  83. scanf("%d",&kase);
  84. while(kase--) {
  85. scanf("%d%d",&n,&m);
  86. build(,n,);
  87. while(m--) {
  88. scanf("%d%d%d",&op,&x,&y);
  89. if(!op) {
  90. scanf("%d",&t);
  91. update(,n,x,y,t,);
  92. } else if(op == ) printf("%d\n",query(,n,x,y,).maxv);
  93. else printf("%I64d\n",query(,n,x,y,).sum);
  94. }
  95. }
  96. return ;
  97. }

哥终于搞清了,感谢 某岛 的代码

本题的做法有点类似于天龙八部里面虚竹那个下棋场景,死而后生

做法就是:每次更新一段区间的时候,把标记放到本区间,然后,我们要兵马未动,粮草先行

先去下面走一遭,统计下面有多少个不大于t,并且这些不大于t的元素的和

这样就能计算出当前区间的和了?不能?那么最大值呢?别逗了,当前区间的最大值肯定是t啦。

tag?要么就是0,要么就是区间的最大值。不是么?

你说这样都不超时真没天理?是的,我也是这么觉得的。。。每次都推到底,这还不超时。。。我也不知道分摊是如何分摊的

下面是搞清真相后写的另一份代码,代码内附有注释,我想这是你目前所能看到的最详细的解说了,毕竟中学生写的代码,可能是有代沟吧

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long LL;
  4. const int maxn = ;
  5. struct node{
  6. LL sum;
  7. int cv,mx,tag;
  8. //cv用来记录该区间有多少个数不大于t
  9. //mx当然是记录区间的最大值
  10. //tag是lazy标识啦,这个线段树常客
  11. //sum...
  12. }tree[maxn<<];
  13. void pushup(int v){
  14. tree[v].sum = tree[v<<].sum + tree[v<<|].sum;
  15. tree[v].mx = max(tree[v<<].mx,tree[v<<|].mx);
  16. tree[v].cv = tree[v<<].cv + tree[v<<|].cv;
  17. }
  18. int tmp;
  19. void build(int lt,int rt,int v){
  20. if(lt == rt){
  21. scanf("%d",&tmp);
  22. tree[v].sum = tree[v].mx = tree[v].tag = tmp;
  23. tree[v].cv = ;
  24. //cv记录的是不大于t的元素个数
  25. return;
  26. }
  27. tree[v].tag = ;
  28. int mid = (lt + rt)>>;
  29. build(lt,mid,v<<);
  30. build(mid+,rt,v<<|);
  31. pushup(v);
  32. }
  33. void modify(int L,int R,int t,int v){
  34. if(tree[v].tag && tree[v].tag <= t) return;
  35. tree[v].tag = t;
  36. //只有可能是tree[v].tag == 0
  37. //因为前面calc的时候已经先行走了一遍
  38. if(tree[v].cv != R - L + ){
  39. //因为当前区间不大于t的元素不算全区间,所以还有比t大的
  40. //大的要置成t,所以mx成了t
  41. tree[v].mx = t;
  42. tree[v].sum += (LL)t*(R - L + - tree[v].cv);
  43. tree[v].cv = R - L + ;
  44. //sum在alc以后 其实代表的是那些不大于t的元素之和
  45. //现在把大于t的都改成t了,那么现在和是多少?
  46. }
  47. }
  48. void pushdown(int L,int R,int v){
  49. if(tree[v].tag){
  50. int mid = (L + R)>>;
  51. modify(L,mid,tree[v].tag,v<<);
  52. modify(mid+,R,tree[v].tag,v<<|);
  53. tree[v].tag = ;
  54. }
  55. }
  56. void calc(int L,int R,int t,int v){
  57. if(tree[v].mx < t) return;
  58. if(tree[v].tag >= t) tree[v].tag = ;
  59. if(L == R){
  60. tree[v].sum = tree[v].mx = tree[v].tag;
  61. tree[v].cv = tree[v].tag?:;
  62. //记录当前不大于t的元素的个数以及他们的和
  63. return;
  64. }
  65. pushdown(L,R,v);
  66. int mid = (L + R)>>;
  67. calc(L,mid,t,v<<);
  68. calc(mid+,R,t,v<<|);
  69. pushup(v);
  70. }
  71. void update(int L,int R,int lt,int rt,int t,int v){
  72. if(tree[v].mx <= t) return;
  73. if(lt <= L && rt >= R){
  74. if(L == R){
  75. tree[v].sum = tree[v].tag = tree[v].mx = t;
  76. tree[v].cv = ;
  77. //强行修改为t,毕竟此处是大于t的,如果不大于t前面return了
  78. }else calc(L,R,t,v);//先行遍历到底,兵马未动,粮草先行
  79. modify(L,R,t,v);
  80. }else{
  81. pushdown(L,R,v);
  82. int mid = (L + R)>>;
  83. if(lt <= mid) update(L,mid,lt,rt,t,v<<);
  84. if(rt > mid) update(mid+,R,lt,rt,t,v<<|);
  85. pushup(v);
  86. }
  87. }
  88. int queryMax(int L,int R,int lt,int rt,int v){
  89. if(lt <= L && rt >= R) return tree[v].mx;
  90. int mid = (L + R)>>,mx = INT_MIN;
  91. pushdown(L,R,v);
  92. if(lt <= mid) mx = max(mx,queryMax(L,mid,lt,rt,v<<));
  93. if(rt > mid) mx = max(mx,queryMax(mid+,R,lt,rt,v<<|));
  94. pushup(v);
  95. return mx;
  96. }
  97. LL querySum(int L,int R,int lt,int rt,int v){
  98. if(lt <= L && rt >= R) return tree[v].sum;
  99. int mid = (L + R)>>;
  100. LL sum = ;
  101. pushdown(L,R,v);
  102. if(lt <= mid) sum += querySum(L,mid,lt,rt,v<<);
  103. if(rt > mid) sum += querySum(mid+,R,lt,rt,v<<|);
  104. pushup(v);
  105. return sum;
  106. }
  107. int main(){
  108. int kase,n,m,op,x,y,t;
  109. scanf("%d",&kase);
  110. while(kase--){
  111. scanf("%d%d",&n,&m);
  112. build(,n,);
  113. while(m--){
  114. scanf("%d%d%d",&op,&x,&y);
  115. if(x > y) swap(x,y);
  116. if(!op){
  117. scanf("%d",&t);
  118. update(,n,x,y,t,);
  119. }else if(op == ) printf("%d\n",queryMax(,n,x,y,));
  120. else printf("%I64d\n",querySum(,n,x,y,));
  121. }
  122. }
  123. return ;
  124. }

2015 Multi-University Training Contest 2 hdu 5306 Gorgeous Sequence的更多相关文章

  1. 2015 Multi-University Training Contest 6 hdu 5357 Easy Sequence

    Easy Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  2. HDU 5306 Gorgeous Sequence[线段树区间最值操作]

    Gorgeous Sequence Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  3. 2016 Multi-University Training Contest 10 || hdu 5860 Death Sequence(递推+单线约瑟夫问题)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5860 题目大意:给你n个人排成一列编号,每次杀第一个人第i×k+1个人一直杀到没的杀.然后 ...

  4. HDU 5306 Gorgeous Sequence

    如果维护max,sum,那么可以得到一个暴力方法,如果t>=max,那可以return,否则往下更新,显然超时. 在上面基础上,再维护一下次大值,与最大值的个数.这样一来,次大值<t< ...

  5. [HDU] 5306 Gorgeous Sequence [区间取min&求和&求max]

    题解: 线段树维护区间取min求和求max 维护最小值以及个数,次小值 标记清除时,分情况讨论 当lazy>max1 退出 当max1>lazy>max2(注意不要有等号) 更新 否 ...

  6. HDU - 5306 Gorgeous Sequence (吉司机线段树)

    题目链接 吉司机线段树裸题... #include<bits/stdc++.h> using namespace std; typedef long long ll; ,inf=0x3f3 ...

  7. HDU - 5306 Gorgeous Sequence 线段树 + 均摊分析

    Code: #include<algorithm> #include<cstdio> #include<cstring> #define ll long long ...

  8. 2015 Multi-University Training Contest 8 hdu 5390 tree

    tree Time Limit: 8000ms Memory Limit: 262144KB This problem will be judged on HDU. Original ID: 5390 ...

  9. 2015 Multi-University Training Contest 8 hdu 5383 Yu-Gi-Oh!

    Yu-Gi-Oh! Time Limit: 2000ms Memory Limit: 65536KB This problem will be judged on HDU. Original ID:  ...

随机推荐

  1. CF833B The Bakery (线段树+DP)

    题目大意:给你一个序列(n<=35000),最多分不大于m块(m<=50),求每个块内不同元素的数量之和的最大值 考试的时候第一眼建图,没建出来,第二眼贪心 ,被自己hack掉了,又随手写 ...

  2. 数据库范式1NF 2NF 3NF BCNF(实例)通俗易懂的讲解

    [转] 数据库范式1NF 2NF 3NF BCNF(实例)通俗易懂的讲解     本文对大多数初学数据库原理的同学绝对是个大福利,哈哈,完完整整的看完此篇博文一定能够清晰地理解数据库的四大范式.    ...

  3. SQL SERVER-identity | @@identity | scope_identity

    主键自增 IDENTITY(1,1),MS SQL Server 使用 IDENTITY 关键字来执行 auto-increment 任务. 在上面的实例中,IDENTITY 的开始值是 1,每条新记 ...

  4. HTML5与后台服务器的数据流动问题

    编辑中,尚未完稿...2017.7.14 1345 很多前端开发出来的HTML5可能对于后台开发者来说,并不是很清楚,也许像我一样一知半解.而且真的让人很糊涂的地方就是前端的JS如何与后端的数据库进行 ...

  5. java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start com

    错误如题. 原因:web.xml中的servlet映射<url-pattern> 配置错误 改动正确就可以. 我直接删除了,bug就攻克了. 另一个问题是 xxx.jar fail to ...

  6. leveldb学习:sstable(2)

    block写入:block_builder block.h和.cc里定义了block的entry存储格式和restart,提供了entry的查找接口以及迭代器.那么怎样往写block里写entry呢? ...

  7. bzoj5204: [CodePlus 2018 3 月赛]投票统计(离散化+暴力)

    5204: [CodePlus 2018 3 月赛]投票统计 题目:传送门 题解: 谢谢niang老师的一道sui题 离散化之后直接搞啊(打完之后还错了...) 代码: #include<cst ...

  8. [Swift]数组(Array)最强解析

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  9. jqGrid添加删除功能(不和数据库交互)

    jqGrid添加删除功能(不和数据库交互) 一.背景需求 项目中需要在前端页面动态的添加行,删除行,上下移动行等,同时还不和数据库交互.一直在用jqGrid展示表格的我们,从没有深入的研究过它,当然看 ...

  10. jsp表单验证格式