题面

100

在\(O(n^2)\)的基础上,我们可以用线段树来加速。

枚举了左端点之后,需要知道以这个左端点为起点的前缀max,前缀min。

这里只讨论前缀max,前缀min同理。

当我们倒序枚举左端点的时候,这个前缀max就可以用线段树来维护:

左端点向左移一位到i——

首先我们要预处理出a[i]向右第一个比他小的,以及第一个比他大的。

然后就相当于是区间赋值,并在线段树中维护好每一位的min和max积之和。

时间复杂度为\(O(nlogn)\)。

code

#include<bits/stdc++.h>
#define ll long long
#define fo(i,x,y) for(int i=x;i<=y;i++)
#define fd(i,x,y) for(int i=x;i>=y;i--)
using namespace std;
const char* fin="seq.in";
const char* fout="seq.out";
const int inf=0x7fffffff;
int read(){
int x=0;
char ch=getchar();
while (ch<'0' || ch>'9') ch=getchar();
while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return x;
}
const int maxn=500007,mo=1000000007;
int n,a[maxn],ans,mx[maxn],mn[maxn],st[maxn];
struct node{int x,a,b,ma,mb;node(){ma=mb=-1;}}c[maxn*4];
void mkd(int l,int r,int t){
if (c[t].ma!=-1){
c[t].x=1ll*c[t].b*c[t].ma%mo;
c[t].a=1ll*c[t].ma*(r-l+1)%mo;
if (l<r){
c[t*2].ma=c[t].ma;
c[t*2+1].ma=c[t].ma;
}
c[t].ma=-1;
}
if (c[t].mb!=-1){
c[t].x=1ll*c[t].a*c[t].mb%mo;
c[t].b=1ll*c[t].mb*(r-l+1)%mo;
if (l<r){
c[t*2].mb=c[t].mb;
c[t*2+1].mb=c[t].mb;
}
c[t].mb=-1;
}
}
void modifya(int l,int r,int t,int v1,int v2,int v){
int mid=(l+r)/2;
mkd(l,r,t);
if (l>v2 || r<v1) return;
if (l>=v1 && r<=v2){
c[t].ma=v;
mkd(l,r,t);
return;
}
modifya(l,mid,t*2,v1,v2,v);
modifya(mid+1,r,t*2+1,v1,v2,v);
c[t].x=(c[t*2].x+c[t*2+1].x)%mo;
c[t].a=(c[t*2].a+c[t*2+1].a)%mo;
c[t].b=(c[t*2].b+c[t*2+1].b)%mo;
}
void modifyb(int l,int r,int t,int v1,int v2,int v){
int mid=(l+r)/2;
mkd(l,r,t);
if (l>v2 || r<v1) return;
if (l>=v1 && r<=v2){
c[t].mb=v;
mkd(l,r,t);
return;
}
modifyb(l,mid,t*2,v1,v2,v);
modifyb(mid+1,r,t*2+1,v1,v2,v);
c[t].x=(c[t*2].x+c[t*2+1].x)%mo;
c[t].a=(c[t*2].a+c[t*2+1].a)%mo;
c[t].b=(c[t*2].b+c[t*2+1].b)%mo;
}
int main(){
freopen(fin,"r",stdin);
freopen(fout,"w",stdout);
n=read();
fo(i,1,n) a[i]=read();
st[0]=0;
fd(i,n,1){
while (st[0] && a[st[st[0]]]>=a[i]) st[0]--;
if (!st[0]) mx[i]=n+1;
else mx[i]=st[st[0]];
st[++st[0]]=i;
}
st[0]=0;
fd(i,n,1){
while (st[0] && a[st[st[0]]]<=a[i]) st[0]--;
if (!st[0]) mn[i]=n+1;
else mn[i]=st[st[0]];
st[++st[0]]=i;
}
fd(i,n,1){
modifya(1,n,1,i,mx[i]-1,a[i]);
modifyb(1,n,1,i,mn[i]-1,a[i]);
ans=(ans+c[1].x)%mo;
}
printf("%d",ans);
return 0;
}

最新文章

  1. 如何为你的微信小程序体积瘦身?
  2. Entity Framework 6 Recipes 2nd Edition(10-6)译 -&gt; TPT继承模型中使用存储过程
  3. oracle 表字段添加 修改 删除语法
  4. 2016-2017 ACM-ICPC, NEERC, Southern Subregional Contest (Online Mirror) in codeforces(codeforces730)
  5. Lazyr.js – 延迟加载图片(Lazy Loading)
  6. smarty foreach循环
  7. iOS的 context 和Android 中的 canvas
  8. matlab和C/C++混合编程--Mex (六)参数传递
  9. 模仿 &quot;淘宝彩票&quot; 的随机选球投注效果!
  10. mmc生产运输问题
  11. leetcode先刷_Search in Rotated Sorted Array II
  12. 你的float用对了吗
  13. JavaWeb三层结构---课设02
  14. 将字符串当做是php代码执行的函数eavl()
  15. org.apache.commons.lang.StringUtils 中 Join 函数
  16. Mybatis中的Caused by: org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): 找不到Mapper.xml文件的问题
  17. 【菜鸟学Python】案例一:汇率换算
  18. KMP模板(HDU1711)
  19. gnuradio 创建cos_source
  20. STM32F103X datasheet学习笔记---Interrupts and events

热门文章

  1. 查看java资源的占用
  2. Ubuntu 18.04 Linux上安装Etherpad,基于Web的实时协作编辑器
  3. 自己编写jquery插件
  4. React报错:Laravel React-Router browserHistory 刷新子页面报错404
  5. 《DSP using MATLAB》Problem 7.36
  6. js时间操作getTime(),ios移动端真机上返回显示NAN
  7. 04_Spring AOP两种代理方法
  8. .Net Core微服务系列--配置中心
  9. jmeter参数化之用户参数
  10. Ajax请求参数传到后台为空