【BZOJ4262】Sum

Description

Input

第一行一个数 t,表示询问组数。
第一行一个数 t,表示询问组数。
接下来 t 行,每行四个数 l_1, r_1, l_2, r_2。

Output

一共 t 行,每行一个数 Sum。

Sample Input

4
1 3 5 7
2 4 6 8
1 1 9 9
9 9 1 1

Sample Output

9322587654
9025304064
1065645568
0

HINT

1<=t<=40000,1<=L1<R1<=10^5,1<=L2<=R2<=10^5

题解:我们分开考虑max和pre的情况。我们将max(i...j)视为二维平面上点(i,j)的权值,处理出每个数左边第一个比它大的数,然后这个数的贡献区间可以就看成一个矩形(或三角形),而询问就变成了求平面上一个矩形区域的权值和。可以用线段树来搞。

不过线段树维护历史总和还真是不容易,打标记的部分还是好好说说吧。

维护三个值:v代表当前的区间和,s代表历史的v之和,l代表区间长度。
维护四个标记:a,b,c,d,代表标记生效后,v=a*v+b*l,s=s+c*v+d*l。

关键在于标记如何合并。假如我们要将x和y的标记合并成z。

a:显然z.a=x.a*y.a即可。
b:先要*=y.a,还要+=y.b。
c:+=x.a*y.c。
d:先要+=y.d,还要+=x.b*y.c。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <algorithm>
  5. #define lson x<<1
  6. #define rson x<<1|1
  7. using namespace std;
  8. const int maxn=100010;
  9. typedef long long ll;
  10. struct Tag
  11. {
  12. ll a,b,c,d;
  13. Tag () {a=1,b=c=d=0;}
  14. Tag (ll A,ll B,ll C,ll D) {a=A,b=B,c=C,d=D;}
  15. Tag operator + (const Tag &x) const {return Tag(a*x.a,b*x.a+x.b,a*x.c+c,d+b*x.c+x.d);}
  16. };
  17. struct node
  18. {
  19. ll v,s,l;
  20. Tag t;
  21. node () {v=s=l=0,t=Tag();}
  22. node (ll a,ll b,ll c,Tag d) {v=a,s=b,l=c,t=d;}
  23. inline void add(Tag x)
  24. {
  25. s=s+v*x.c+l*x.d,v=v*x.a+l*x.b,t=t+x;
  26. }
  27. node operator + (const node &a) const
  28. {
  29. return node(v+a.v,s+a.s,l+a.l,Tag());
  30. }
  31. }s[maxn<<2];
  32. int m,n,top;
  33. ll ans[maxn],v[maxn];
  34. int st[maxn],pre[maxn];
  35. struct QUERY
  36. {
  37. int x,l,r,org,k;
  38. }q[maxn];
  39. bool cmp(const QUERY &a,const QUERY &b)
  40. {
  41. return a.x<b.x;
  42. }
  43. inline void pushdown(int x)
  44. {
  45. if(s[x].t.a!=1||s[x].t.b||s[x].t.c||s[x].t.d) s[lson].add(s[x].t),s[rson].add(s[x].t),s[x].t=Tag();
  46. }
  47. void build(int l,int r,int x)
  48. {
  49. if(l==r)
  50. {
  51. s[x]=node(),s[x].l=1;
  52. return ;
  53. }
  54. int mid=(l+r)>>1;
  55. build(l,mid,lson),build(mid+1,r,rson);
  56. s[x]=s[lson]+s[rson];
  57. }
  58. void updata(int l,int r,int x,int a,int b,Tag t)
  59. {
  60. if(a>b) return ;
  61. if(a<=l&&r<=b)
  62. {
  63. s[x].add(t);
  64. return ;
  65. }
  66. pushdown(x);
  67. int mid=(l+r)>>1;
  68. if(a<=mid) updata(l,mid,lson,a,b,t);
  69. if(b>mid) updata(mid+1,r,rson,a,b,t);
  70. s[x]=s[lson]+s[rson];
  71. }
  72. node query(int l,int r,int x,int a,int b)
  73. {
  74. if(a<=l&&r<=b) return s[x];
  75. pushdown(x);
  76. int mid=(l+r)>>1;
  77. if(b<=mid) return query(l,mid,lson,a,b);
  78. if(a>mid) return query(mid+1,r,rson,a,b);
  79. return query(l,mid,lson,a,b)+query(mid+1,r,rson,a,b);
  80. }
  81. void work(ll flag)
  82. {
  83. int i,j;
  84. build(1,n,1);
  85. for(j=1;j<=2*m&&!q[j].x;j++);
  86. for(i=1;i<=n;i++)
  87. {
  88. updata(1,n,1,pre[i],i,Tag(0,v[i],0,0)),s[1].add(Tag(1,0,1,0));
  89. for(;j<=2*m&&q[j].x==i;j++) ans[q[j].org]+=flag*q[j].k*query(1,n,1,q[j].l,q[j].r).s;
  90. }
  91. }
  92. inline int rd()
  93. {
  94. int ret=0,f=1; char gc=getchar();
  95. while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
  96. while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
  97. return ret*f;
  98. }
  99. int main()
  100. {
  101. m=rd();
  102. int i;
  103. ll t1=1,t2=1;
  104. for(i=1;i<=m;i++) q[i].l=q[i+m].l=rd(),q[i].r=q[i+m].r=rd(),q[i].x=rd()-1,q[i+m].x=rd(),
  105. n=max(n,q[i+m].x),q[i].k=-1,q[i+m].k=1,q[i].org=q[i+m].org=i;
  106. for(i=1;i<=n;i++) t1=t1*1023%1000000000,t2=t2*1025%1000000000,v[i]=t1^t2;
  107. sort(q+1,q+2*m+1,cmp);
  108. for(i=1;i<=n;i++)
  109. {
  110. while(top&&v[st[top]]>=v[i]) top--;
  111. pre[i]=st[top]+1,st[++top]=i;
  112. }
  113. work(-1);
  114. for(top=0,i=1;i<=n;i++)
  115. {
  116. while(top&&v[st[top]]<=v[i]) top--;
  117. pre[i]=st[top]+1,st[++top]=i;
  118. }
  119. work(1);
  120. for(i=1;i<=m;i++) printf("%lld\n",ans[i]);
  121. return 0;
  122. }

【BZOJ4262】Sum 单调栈+线段树的更多相关文章

  1. 洛谷P4198 楼房重建 单调栈+线段树

    正解:单调栈+线段树 解题报告: 传送门! 首先考虑不修改的话就是个单调栈板子题昂,这个就是 然后这题的话,,,我怎么记得之前考试好像有次考到了类似的题目昂,,,?反正我总觉着这方法似曾相识的样子,, ...

  2. 2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树)

    2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树) 传送门:https://nanti.jisuanke.com/t/41296 题意: 给一个数列A 问在数列A中有多 ...

  3. The Preliminary Contest for ICPC China Nanchang National Invitational I. Max answer (单调栈+线段树)

    题目链接:https://nanti.jisuanke.com/t/38228 题目大意:一个区间的值等于该区间的和乘以区间的最小值.给出一个含有n个数的序列(序列的值有正有负),找到该序列的区间最大 ...

  4. 2019南昌网络赛-I(单调栈+线段树)

    题目链接:https://nanti.jisuanke.com/t/38228 题意:定义一段区间的值为该区间的和×该区间的最小值,求给定数组的最大的区间值. 思路:比赛时还不会线段树,和队友在这题上 ...

  5. 网络赛 I题 Max answer 单调栈+线段树

    题目链接:https://nanti.jisuanke.com/t/38228 题意:在给出的序列里面找一个区间,使区间最小值乘以区间和得到的值最大,输出这个最大值. 思路:我们枚举每一个数字,假设是 ...

  6. 南昌邀请赛I.Max answer 单调栈+线段树

    题目链接:https://nanti.jisuanke.com/t/38228 Alice has a magic array. She suggests that the value of a in ...

  7. 南昌网络赛 I. Max answer (单调栈 + 线段树)

    https://nanti.jisuanke.com/t/38228 题意给你一个序列,对于每个连续子区间,有一个价值,等与这个区间和×区间最小值,求所有子区间的最大价值是多少. 分析:我们先用单调栈 ...

  8. 2019ICPC南昌邀请赛网络赛 I. Max answer (单调栈+线段树/笛卡尔树)

    题目链接 题意:求一个序列的最大的(区间最小值*区间和) 线段树做法:用单调栈求出每个数两边比它大的左右边界,然后用线段树求出每段区间的和sum.最小前缀lsum.最小后缀rsum,枚举每个数a[i] ...

  9. 2018宁夏邀请赛 Continuous Intervals(单调栈 线段树

    https://vjudge.net/problem/Gym-102222L 题意:给你n个数的序列,让判断有几个区间满足排完序后相邻两数差都不大于1. 题解:对于一个区间 [L,R],记最大值为 m ...

随机推荐

  1. 设置 TIM3_CH2 的 PWM 模式,使能 TIM3 的 CH2 输出

    /**   ******************************************************************************   * @file    st ...

  2. hibernate开发流程

    开发流程,注意:每个hibernate版本在集成的时候是不太一样的.本次使用的是hibernate-distribution-3.6.10.Final-dist 一.开发流程 1)在数据库中创建表,代 ...

  3. 如果你写PHP, 请多注意自己是否有良好的习惯

    如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍. $row['id'] 的速度是$row[id]的7倍. echo 比 print 快,并且使用echo的多重参数 ...

  4. cocos2dx 3.3 异步加载纹理

    这里以3d场景加载为例,2d情况类似. 先同步加载模型数据和尺寸缩小了100倍的贴图,创建mesh.然后异步加载所有精细纹理并每加载完一个就替换一个,并进入场景. 如此做法的效果是当刚进入场景时看到的 ...

  5. 博客已迁移至512z.com

    本博客已迁移至http://blog.512z.com,此处今后不再更新

  6. mysql多实例安装详解

    首先说明一个场景:我的电脑是ubuntu系统,之前apt-get自动安装过mysql.这也是出现错误最多的原因之一. 安装过程,其中充斥着各种错误: 6.mkdir mysql 7.groupadd  ...

  7. 在iOS App中增加完整的照片多选功能

    转自:http://blog.csdn.net/jasonblog/article/details/8141850 主要参考了ELCImagePickerController,不过由于UI展现上需要定 ...

  8. action(二)

    RemoveSelf :消失 CCFiniteTimeAction* action = CCSequence::create( CCMoveBy::create( , ccp(,)), CCRotat ...

  9. Vs code 通用插件

    Vs code 通用插件 转自:https://segmentfault.com/a/1190000006697219 HTML Snippets 超级实用且初级的 H5代码片段以及提示 HTML C ...

  10. FreeRTOS 定时器组

    以下转载自安富莱电子: http://forum.armfly.com/forum.php 本章节为大家讲解 FreeRTOS 支持的定时器组,或者叫软件定时器,又或者叫用户定时器均可.软件定时器的功 ...