Description

Input

第1行,一个整数N;

第2~n+1行,每行一个整数表示序列a。

Output

输出答案对10^9取模后的结果。

Sample Input

4

2

4

1

4

Sample Output

109

【数据范围】

N <= 500000

1 <= a_i <= 10^8

Solution

这题目好麻烦

考虑所有子区间问题的贡献可以考虑分治

假设当前到达 \(l,r\) 区间,计算跨过 \(mid\) 的贡献

一个指针 \(x\) 从 \(mid\) 往 \(l\) 枚举,枚举的过程中可以维护 \(a\) 和 \(b\) ,分别代表 \([x,mid]\) 的最小值和最大值

再来两个指针 \(p,q\) ,从 \(mid\) 开始往右走,保证 \([mid+1,p]\) 的最小值是 \(a\) ,\([mid+1,q]\) 的最大值是 \(b\) 的最大位置

那么对于当前的 \(x\) 位置,根据右端点的不同,出现了三种区间

  • 右端点小于等于 \(\min \{ p,q \}\) ,这种区间的最小值最大值分别就是 \(a,b\) ,直接算就好了
  • 右端点在 \((\min \{p,q\} ,\max \{p,q\}]\) ,这种区间还要分两种情况,不过其本质是一样的。对于这种区间,我们知道了一个最值,而剩下的最值不知道,这样的话,把式子推出来 \(\sum_{y=\min \{p, q\}+1}^{\max \{p, q\}} (\min_{k = mid}^{y} a_k) \times(y - x + 1) \times b\) (这里是假设 \(p<q\) ),拆开后,可以发现预处理两个前缀和就好了
  • 右端点大于 \(\max \{p,q\}\) ,这种区间也还要推式子,\(\sum_{y=\max \{p, q\}+1}^{r} (\min_{k = mid}^{y} a_k) (\max_{k = mid}^{y} a_k) \times(y - x + 1)\) ,拆开后又发现是某些个前缀和的加加减减,预处理就好了
#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=500000+10,Mod=1e9;
int n,a[MAXN],Mnr[MAXN],Mxr[MAXN];
ll sMn[MAXN],sMx[MAXN],mMn[MAXN],mMx[MAXN],sMxMn[MAXN],mMxMn[MAXN],ans;
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void solve(int l,int r)
{
if(l==r)
{
(ans+=1ll*a[l]*a[r]%Mod)%=Mod;
return ;
}
int Mid=(l+r)>>1,p=Mid,q=Mid,Mnl=a[Mid],Mxl=a[Mid];
solve(l,Mid);solve(Mid+1,r);
sMn[Mid]=sMx[Mid]=mMn[Mid]=mMx[Mid]=sMxMn[Mid]=mMxMn[Mid]=0;
Mnr[Mid+1]=sMn[Mid+1]=Mxr[Mid+1]=sMx[Mid+1]=a[Mid+1];
mMn[Mid+1]=mMx[Mid+1]=1ll*a[Mid+1]*(Mid+1)%Mod;
sMxMn[Mid+1]=1ll*a[Mid+1]*a[Mid+1]%Mod;
mMxMn[Mid+1]=1ll*a[Mid+1]*a[Mid+1]%Mod*(Mid+1)%Mod;
for(register int i=Mid+2;i<=r;++i)
{
Mnr[i]=min(Mnr[i-1],a[i]);
Mxr[i]=max(Mxr[i-1],a[i]);
sMn[i]=(sMn[i-1]+Mnr[i])%Mod;
sMx[i]=(sMx[i-1]+Mxr[i])%Mod;
mMn[i]=(mMn[i-1]+1ll*Mnr[i]*i%Mod)%Mod;
mMx[i]=(mMx[i-1]+1ll*Mxr[i]*i%Mod)%Mod;
sMxMn[i]=(sMxMn[i-1]+1ll*Mnr[i]*Mxr[i]%Mod)%Mod;
mMxMn[i]=(mMxMn[i-1]+1ll*Mnr[i]*Mxr[i]%Mod*i%Mod)%Mod;
}
for(register int x=Mid;x>=l;--x)
{
chkmax(Mxl,a[x]);chkmin(Mnl,a[x]);
while(p<r&&Mnr[p+1]>=Mnl)++p;
while(q<r&&Mxr[q+1]<=Mxl)++q;
int lt=min(p,q),mt=max(p,q);
(ans+=1ll*(1ll*(Mid-x+2+lt-x+1)*(lt-Mid)/2)*Mxl%Mod*Mnl%Mod)%=Mod;
if(p<q)(ans+=(1ll*Mxl*(mMn[mt]-mMn[lt]+Mod)%Mod-1ll*(x-1)*Mxl%Mod*(sMn[mt]-sMn[lt]+Mod)%Mod+Mod)%Mod)%=Mod;
if(p>q)(ans+=(1ll*Mnl*(mMx[mt]-mMx[lt]+Mod)%Mod-1ll*(x-1)*Mnl%Mod*(sMx[mt]-sMx[lt]+Mod)%Mod+Mod)%Mod)%=Mod;
(ans+=((mMxMn[r]-mMxMn[mt]+Mod)%Mod-1ll*(x-1)*(sMxMn[r]-sMxMn[mt]+Mod)%Mod+Mod)%Mod)%=Mod;
}
}
int main()
{
read(n);
for(register int i=1;i<=n;++i)read(a[i]);
solve(1,n);
write(ans,'\n');
return 0;
}

【刷题】BZOJ 3745 [Coci2015]Norma的更多相关文章

  1. BZOJ 3745: [Coci2015]Norma(分治)

    题意 给定一个正整数序列 \(a_1, a_2, \cdots, a_n\) ,求 \[ \sum_{i=1}^{n} \sum_{j=i}^{n} (j - i + 1) \min(a_i,a_{i ...

  2. bzoj 3745 [Coci2015]Norma——序列分治

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3745 如果分治,就能在本层仅算过 mid 的区间了. 可以从中间到左边地遍历左边,给右边两个 ...

  3. bzoj 3745: [Coci2015]Norma

    Description Solution 考虑分治: 我们要统计跨越 \(mid\) 的区间的贡献 分最大值和最小值所在位置进行讨论: 设左边枚举到了 \(i\),左边 \([i,mid]\) 的最大 ...

  4. bzoj 3745: [Coci2015]Norma【分治】

    参考:https://blog.csdn.net/lych_cys/article/details/51203960 真的不擅长这种-- 分治,对于一个(l,r),先递归求出(l,mid),(mid+ ...

  5. 【刷题】BZOJ 2407 探险

    Description 探险家小T好高兴!X国要举办一次溶洞探险比赛,获奖者将得到丰厚奖品哦!小T虽然对奖品不感兴趣,但是这个大振名声的机会当然不能错过! 比赛即将开始,工作人员说明了这次比赛的规则: ...

  6. 【刷题】BZOJ 4543 [POI2014]Hotel加强版

    Description 同OJ3522 数据范围:n<=100000 Solution dp的设计见[刷题]BZOJ 3522 [Poi2014]Hotel 然后发现dp的第二维与深度有关,于是 ...

  7. 【刷题】BZOJ 4316 小C的独立集

    Description 图论小王子小C经常虐菜,特别是在图论方面,经常把小D虐得很惨很惨. 这不,小C让小D去求一个无向图的最大独立集,通俗地讲就是:在无向图中选出若干个点,这些点互相没有边连接,并使 ...

  8. 【刷题】BZOJ 4176 Lucas的数论

    Description 去年的Lucas非常喜欢数论题,但是一年以后的Lucas却不那么喜欢了. 在整理以前的试题时,发现了这样一道题目"求Sigma(f(i)),其中1<=i< ...

  9. BZOJ第一页刷题计划

    BZOJ第一页刷题计划 已完成:67 / 90 [BZOJ1000]A+B Problem:A+B: [BZOJ1001][BeiJing2006]狼抓兔子:最小割: [BZOJ1002][FJOI2 ...

随机推荐

  1. python_环境的配置

    1.首先登入官网:https://www.python.org/downloads/windows/ 下载: 下载executable installer 2.安装 ipython,jupyter 地 ...

  2. VB CompactDatabase 压缩/修复数据库

    Option Explicit Private Sub Command1_Click() On Error GoTo err Dim DbEngine, dbFile As String dbFile ...

  3. 20155238 2016-2017-2 《JAVA程序设计》第八周学习总结

    教材学习内容总结 第十四章 NIO NIO使用频道(Channel)来衔接数据节点,处理数据时,NIO可以让你设定缓冲区(Buffer)容量, 在缓冲区对感兴趣的数据区块进行标记,对于这些标记,提供了 ...

  4. vue build,本地正常访问,服务器上,网页一刷新是404,解决办法

    服务器报错如下图: 此原因,是服务器配置的原因,跟build代码本身无关 以ftp为例,在/etc/nginx/conf.d文件夹下,找到xxx.conf,修改成自己需要的路径即可 位置如下两张图:

  5. python高并发和多线程的关系

    “高并发和多线程”总是被一起提起,给人感觉两者好像相等,实则 高并发 ≠ 多线程 多线程是完成任务的一种方法,高并发是系统运行的一种状态,通过多线程有助于系统承受高并发状态的实现.   高并发是一种系 ...

  6. BigDecimal工具类

    package config_service.slowcity; import java.math.BigDecimal; public class ConfigServerApp { /* * 小数 ...

  7. 通过监控Nginx日志来实时屏蔽高频恶意访问的IP

    目前在我的VPS上主要通过两种方式来限制ip的访问次数. 通过Nginx的limit_req配置来限制同一ip在一分钟内的访问次数 通过Nginx deny封禁一天内超过指定次数的ip(需要一个监控脚 ...

  8. webug4.0安装

    官网:https://www.webug.org/ 官方版本里安装视频教程 4.26 官网打不开,分享当初存在网盘的 链接:https://pan.baidu.com/s/13rG0TLwuA3Ro0 ...

  9. webstorm开发微信小程序代码提醒(webstorm开发工具)

    使用了微信提供的开发工具是真心难用,卡顿厉害.中英文切写注释换相当不爽.还没办法多开窗口,相信大家也遇到过这种现象. 下边我们介绍下webstorm来开发微信小程序的一些配置: File---sett ...

  10. pycharm 调试 scrapy

    http://blog.csdn.net/shijichao2/article/details/61940931