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. arm学习之汇编跳转指令总结

    目前所知道的跳转指令有 b,bl,bep,bne.他们共同点是都是以b开头,首先从字面上分析:b:是Branch,表示分支.bl:是Branch Link表示带连接的分支.bep:Branch ,Eq ...

  2. 设计模式 笔记 命令模式 Command

    //---------------------------15/04/25---------------------------- //Conmmand  命令模式----对象行为型模式 /* 1:意 ...

  3. 红黑树的删除详解与思路分析——不同于教科书上的算法(dart语言实现)

    对于红黑树的删除,看了数据结构的书,也看了很多网上的讲解和实现,但都不满意.很多讲解都是囫囵吞枣,知其然,不知其所以然,讲的晦涩难懂. 红黑树是平衡二叉树的一种,其删除算法是比较复杂的,因为删除后还要 ...

  4. 智能合约bug以及修改方案

    截取两篇文章:第一遍文章说的是智能合约能不能修改的问题: ETC转到ETH地址以及转币进ETH智能合约账户能不能转出来? 第0章 引言 如果ETC充值到了ETH地址上,能找回来吗?答案是不一定. ET ...

  5. Redis学习笔记之入门基础知识——五种数据类型

    1) 字符串 SET设置值,GET获取值,DEL删除值 INCR key-name将键存储的值加上1       DECR key-name将键存储的值减去1 INCRBY key-name amou ...

  6. 《Linux内核 》MOOC 课程

    姬梦馨 原创微博 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 学习笔记 一:什么是冯诺依曼体系结构? ...

  7. Linux内核分析作业第二周

    操作系统是如何工作的 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.函数调用堆栈 1.计算机工作三 ...

  8. 《Linux内核分析》第二周:操作系统是如何工作的

    杨舒雯 20135324 北京电子科技学院 杨舒雯 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1 ...

  9. 毕业设计---jQuery动态生成的a标签的事件绑定

    这几天在毕业设计的前端设计阶段,准备放弃使用jsp,完全通过html+ajax+SSH进行网站的编写,在前端的页面显示我准备使用jQuery来实现数据的动态绑定.但是遇到动态添加的a标签无法直接通过$ ...

  10. 阅读c#程序——回答问题

    c#“小”程序: using System; using System.Collections.Generic; using System.Text; namespace FindTheNumber ...