https://acm.hdu.edu.cn/showproblem.php?pid=6989
题意:
定义一个区间[L,R]的平均值为(最大值+最小值)/2
若干次询问[l,r],求[l,r]子区间平均值的期望
对[l,r]求所有子区间的最大值之和+最小值之和
然后除以2再除以子区间个数
求子区间最小(大)值之和,是HNOI2016的一道题
https://www.cnblogs.com/TheRoadToTheGold/p/15150757.html
搬过来用即可
#include<bits/stdc++.h> using namespace std; #define N 200003 typedef long long LL; int a[N]; int s[N],top; LL fl[N],fr[N],gl[N],gr[N]; LL FL[N],FR[N],GL[N],GR[N]; int lg2[N]; int st[N][18],stp[N][18]; int ST[N][18],STP[N][18]; const int mod=1e9+7; int query(int l,int r) { int len=lg2[r-l+1]; if(st[l][len]<st[r-(1<<len)+1][len]) return stp[l][len]; return stp[r-(1<<len)+1][len]; } int QUERY(int l,int r) { int len=lg2[r-l+1]; if(ST[l][len]>ST[r-(1<<len)+1][len]) return STP[l][len]; return STP[r-(1<<len)+1][len]; } int poww(int a,int b) { int c=1; for(;b;a=1ll*a*a%mod,b>>=1) if(b&1) c=1ll*c*a%mod; return c; } int main() { int T; int n,m; int l,r,p,P; long long ans; int inv2=poww(2,mod-2); for(int i=2;i<N;++i) lg2[i]=lg2[i>>1]+1; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) scanf("%d",&a[i]); for(int i=1;i<=n;++i) { st[i][0]=ST[i][0]=a[i]; stp[i][0]=STP[i][0]=i; } for(int i=1;1<<i<=n;++i) for(int j=1;j+(1<<i)-1<=n;++j) { st[j][i]=min(st[j][i-1],st[j+(1<<i-1)][i-1]); if(st[j][i]==st[j][i-1]) stp[j][i]=stp[j][i-1]; else stp[j][i]=stp[j+(1<<i-1)][i-1]; } for(int i=1;1<<i<=n;++i) for(int j=1;j+(1<<i)-1<=n;++j) { st[j][i]=min(st[j][i-1],st[j+(1<<i-1)][i-1]); ST[j][i]=max(ST[j][i-1],ST[j+(1<<i-1)][i-1]); if(st[j][i]==st[j][i-1]) stp[j][i]=stp[j][i-1]; else stp[j][i]=stp[j+(1<<i-1)][i-1]; if(ST[j][i]==ST[j][i-1]) STP[j][i]=STP[j][i-1]; else STP[j][i]=STP[j+(1<<i-1)][i-1]; } a[0]=-2e9; s[top=0]=0; for(int i=1;i<=n;++i) { while(a[i]<=a[s[top]]) top--; fl[i]=(fl[s[top]]+1ll*(i-s[top])*a[i])%mod; gl[i]=gl[i-1]+fl[i]; gl[i]%=mod; s[++top]=i; } a[n+1]=-2e9; s[top=0]=n+1; for(int i=n;i;--i) { while(a[i]<=a[s[top]]) top--; fr[i]=(fr[s[top]]+1ll*(s[top]-i)*a[i])%mod; gr[i]=gr[i+1]+fr[i]; gr[i]%=mod; s[++top]=i; } a[0]=2e9; s[top=0]=0; for(int i=1;i<=n;++i) { while(a[i]>=a[s[top]]) top--; FL[i]=(FL[s[top]]+1ll*(i-s[top])*a[i])%mod; GL[i]=GL[i-1]+FL[i]; GL[i]%=mod; s[++top]=i; } a[n+1]=2e9; s[top=0]=n+1; for(int i=n;i;--i) { while(a[i]>=a[s[top]]) top--; FR[i]=(FR[s[top]]+1ll*(s[top]-i)*a[i])%mod; GR[i]=GR[i+1]+FR[i]; GR[i]%=mod; s[++top]=i; } for(int i=1;i<=m;++i) { scanf("%d%d",&l,&r); p=query(l,r); ans=1ll*(p-l+1)*(r-p+1)%mod*a[p]%mod; ans+=gr[l]-gr[p]-1ll*fr[p]*(p-l)%mod; ans+=gl[r]-gl[p]-1ll*fl[p]*(r-p)%mod; P=QUERY(l,r); ans+=1ll*(P-l+1)*(r-P+1)%mod*a[P]%mod; ans+=GR[l]-GR[P]-1ll*FR[P]*(P-l)%mod; ans+=GL[r]-GL[P]-1ll*FL[P]*(r-P)%mod; ans%=mod; if(ans<0) ans+=mod; ans=ans*inv2%mod; ans=ans*poww(1ll*(r-l+1)*(r-l+2)/2%mod,mod-2)%mod; printf("%lld ",ans); } } }