版权声明:虽然本蒟蒻很菜,但各位dalao转载请注明出处谢谢。 https://blog.csdn.net/xuxiayang/article/details/86668058
求
分治算法,分而治之。
#pragma GCC optimize(2)
#include<cstdio>
#include<cctype>
#include<algorithm>
#define wyc 1000000007
#define r(i,a,b) for(register int i=a;i<=b;i++)
#define d(i,a,b) for(register int i=a;i>=b;i--)
using namespace std;int n;
long long ans,s[500001],s1[500001],s2[500001],a[500001],mx[500001],mi[500001];
inline char Getchar()
{
static char buf[10000000],*p1=buf+10000000,*pend=buf+10000000;
if(p1==pend)
{
p1=buf; pend=buf+fread(buf,1,10000000,stdin);
if (pend==p1) return -1;
}
return *p1++;
}
inline long long read()
{
char c;int d=1;long long f=0;
while(c=Getchar(),!isdigit(c))if(c==45)d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=Getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
inline void dfs(int l,int r)
{
if(l>r) return;
if(l==r) {(ans+=a[l]*a[l])%=wyc;return;}
int mid=l+r>>1;mx[mid]=mi[mid]=a[mid];
d(i,mid-1,l) mx[i]=max(mx[i+1],a[i]),mi[i]=min(mi[i+1],a[i]);
r(i,mid+1,r) mx[i]=max(mx[i-1],a[i]),mi[i]=min(mi[i-1],a[i]);//预处理最大最小值
(s[l]=mx[l]*mi[l])%=wyc;s1[l]=mx[l];s2[l]=mi[l];s[l-1]=s1[l-1]=s2[l-1]=0;
r(i,l+1,mid) s[i]=(mx[i]*mi[i]%wyc+s[i-1])%wyc,s1[i]=(s1[i-1]+mx[i])%wyc,s2[i]=(s2[i-1]+mi[i])%wyc;//预处理它们的前缀和及它们乘积的前缀和
int p=mid,q=mid;
r(i,mid,r)//以下指针乱搞即可
{
while(p>=l&&mx[p]<mx[i]) p--;
while(q>=l&&mi[q]>mi[i]) q--;
(ans+=s[min(p,q)])%=wyc;
(ans+=(mid-max(p,q))*mx[i]%wyc*mi[i]%wyc)%=wyc;
if(p<=q) (ans+=mx[i]*(s2[q]-s2[p])%wyc)%wyc;
else (ans+=mi[i]*(s1[p]-s1[q])%wyc)%wyc;
}
dfs(l,mid-1);dfs(mid+1,r);
}
signed main()
{
freopen("seq.in","r",stdin);
freopen("seq.out","w",stdout);
n=read();
for(register int i=1;i<=n;i++) a[i]=read();
dfs(1,n);
printf("%lld\n",ans);
}