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. Java IO详解(七)------随机访问文件流

    File 类的介绍:http://www.cnblogs.com/ysocean/p/6851878.html Java IO 流的分类介绍:http://www.cnblogs.com/ysocea ...

  2. 避免代码merge后无法构建发布(GItlabCI + Jenkins)

    1.准备工作 目标: 开发人员提交代码后触发GitlabCI ,如果有merge请求则触发Jenkins对源分支在开发环境构建测试. 2.GItlab配置 开启仅允许pipeline成功后才能merg ...

  3. 大数据入门第十二天——sqoop入门

    一.概述 1.sqoop是什么 从其官网:http://sqoop.apache.org/ Apache Sqoop(TM) is a tool designed for efficiently tr ...

  4. 使用Fortify进行代码静态分析(系列文章)

    BUG级别:低 Code Correctness(代码正确性) 1.Class does not Implement Equals(类未能实现Equals方法) Dead Code(死亡代码) 1.U ...

  5. python 翻转棋(othello)

    利用上一篇的框架,再写了个翻转棋的程序,为了调试minimax算法,花了两天的时间. 几点改进说明: 拆分成四个文件:board.py,player.py,ai.py,othello.py.使得整个结 ...

  6. Ms.office2010安装教程

    下面用到的软件下载地址如下:http://pan.baidu.com/s/1c08cxPI 第一步 1. 将压缩包office2010.rar解压解压后,会出现一个office2010文件夹如图1.1 ...

  7. linux下的tar命令详解

    通过SSH访问服务器,难免会要用到压缩,解压缩,打包,解包等,这时候tar命令就是是必不可少的一个功能强大的工具.linux中最流行的tar是麻雀虽小,五脏俱全,功能强大. tar命令可以为linux ...

  8. NodeJS旅程 : express - nodejs MVC 中的王牌

    express 正如ASP.NET MVC 在作为.net平台下最佳的 Mvc框架的地位一样,express在 node.js 环境也有着相同的重要性.在百度上 "nodejs expres ...

  9. GPT & UEFI Install Windows7

    安装介质以FAT或者FAT32分区安装介质添加UEFI支持文件(Windows7及其以前的系统,不支持UEFI启动) 从Windows8的安装文件中提取Bootmgfw.efi文件,重命名为BOOTX ...

  10. Daily Scrumming* 2015.12.13(Day 5)

    一.团队scrum meeting照片 二.今日总结 姓名 WorkItem ID 工作内容 签入链接以及备注说明  江昊 任务1063 查找与学习前端工具库,并写出一篇指导文档 https://gi ...