# bzoj3745: [Coci2015]Norma

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const LL mod=1e9;
LL getsum(LL st,LL ed){return ((st+ed)*(ed-st+1)/2)%mod;}//等差数列求和
LL MOD(LL x){return (x%mod+mod)%mod;}

LL a[510000],ans;
struct Right
{
LL st,ed,rmn,rmx;
Right(){}
Right(LL ST,LL ED,LL RMN,LL RMX){st=ST,ed=ED,rmn=RMN;rmx=RMX;}
}R[510000];int Rlen;

LL g[510000],h[510000];
void cdq(LL l,LL r)
{
if(l==r){ans=(ans+a[l]*a[l])%mod;return ;}
int mid=(l+r)/2;

LL rmn=a[mid+1],rmx=a[mid+1]; Rlen=0;
R[++Rlen]=Right(mid+1,mid+1,rmn,rmx);
for(int i=mid+2;i<=r;i++)
{
if(rmn>a[i]||rmx<a[i])
{
rmn=min(rmn,a[i]);
rmx=max(rmx,a[i]);
R[++Rlen]=Right(i,i,rmn,rmx);
}
else R[Rlen].ed++;
}

//--------------------分块----------------------

g[Rlen+1]=0;h[Rlen+1]=0;
for(int i=Rlen;i>=1;i--)
{
g[i]= (g[i+1] + (getsum(R[i].st,R[i].ed)*(R[i].rmn*R[i].rmx%mod))%mod )%mod;
h[i]= (h[i+1] + ((R[i].ed-R[i].st+1)*(R[i].rmn*R[i].rmx%mod))%mod )%mod;
}

//-----------------------右区间预处理函数g，h------------------------

LL j=0,k=0;    int w=-1;LL Gmn=0,Hmn=0,Gmx=0,Hmx=0;//动态维护中部答案
LL lmn=(1LL<<62),lmx=0;
for(LL i=mid;i>=l;i--)
{
lmn=min(lmn,a[i]);
lmx=max(lmx,a[i]);

while(j<Rlen&&(lmn<=R[j+1].rmn&&lmx>=R[j+1].rmx))
{
j++;
if(j<=k)
{
if(w==0)
{
Gmx=MOD( Gmx-(getsum(R[j].st,R[j].ed)*R[j].rmx%mod) );
Hmx=MOD( Hmx-((R[j].ed-R[j].st+1)*R[j].rmx%mod) );
}
else
{
Gmn=MOD( Gmn-(getsum(R[j].st,R[j].ed)*R[j].rmn%mod) );
Hmn=MOD( Hmn-((R[j].ed-R[j].st+1)*R[j].rmn%mod) );
}
}
}

while(k<Rlen&&(lmn<=R[k+1].rmn||lmx>=R[k+1].rmx))
{
k++;
if(lmn<=R[k].rmn&&lmx>=R[k].rmx)
Gmn=0, Hmn=0, Gmx=0, Hmx=0;
else
{
w=(lmn<=R[k].rmn)?0:1;
if(w==0)
{
Gmx=( Gmx+(getsum(R[k].st,R[k].ed)*R[k].rmx%mod) )%mod;
Hmx=( Hmx+((R[k].ed-R[k].st+1)*R[k].rmx%mod) )%mod;
}
else
{
Gmn=( Gmn+(getsum(R[k].st,R[k].ed)*R[k].rmn%mod) )%mod;
Hmn=( Hmn+((R[k].ed-R[k].st+1)*R[k].rmn%mod) )%mod;
}
}
}

//-------------------extend&&单调维护中部-------------------------

if(j>0&&j<=r)ans=( ans + ( MOD(getsum(mid+1,R[j].ed)-((R[j].ed-mid)*(i-1)%mod)) * ((lmn*lmx)%mod) %mod ) )%mod;
//左区间

if(j+1<=k)
{
if(w==0)ans=( ans + lmn*MOD(Gmx-((i-1)*Hmx))%mod )%mod;
else    ans=( ans + lmx*MOD(Gmn-((i-1)*Hmn))%mod )%mod;
}
//中部

if(k+1<=r)ans=( ans + MOD( g[k+1]-((i-1)*h[k+1]%mod) ) )%mod;
//右区间
}

cdq(l,mid),cdq(mid+1,r);
}
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
ans=0;cdq(1,n);
printf("%lld\n",ans);
return 0;
}

pain and happy in the cruel world.
posted @ 2018-09-12 16:52  AKCqhzdy  阅读(166)  评论(0编辑  收藏  举报