考虑计算每个位置的数作为最小值时有多少种情况
方便起见,以位置为第二关键字比较大小,这样就不会出现“相同的”数
可以方便地计算出以i位置为最小值的区间端点的可行位置:[A,i],[i,B]
这是我选的一个区间,那么另一个区间会有两种情况:在[A,B]的范围内或者不在
不妨只考虑另一个区间在i这个区间的右边的情况,设这另一个区间是[l,r]
这种时候第一个区间的左端点是在[A,i]随便选的
第一种情况:
如果l<=B,那么r显然也<=B,所以i<=第一个区间的右端点<l<=r<=B,发现方案数只与[i,B]这个区间的长度有关,可以由公式算出,或者是提前预处理推出
第二种情况:
如果l>B,我还要保证[l,r]内的所有数都大于a[i],这种情况和第一个区间绝对不相交,所以第一个区间的右端点也可以随便选。可以用树状数组维护左端点>x的可选的区间个数
那么我可以按照数字从大到小做,给每个位置维护一个并查集,表示从这个点可延伸出的最远的端点(在这个范围内的数都>=now)
这样,A和B也就顺便算出来了
1 #include<bits/stdc++.h> 2 #define CLR(a,x) memset(a,x,sizeof(a)) 3 #define MP make_pair 4 using namespace std; 5 typedef long long ll; 6 typedef unsigned long long ull; 7 typedef pair<int,int> pa; 8 const int maxn=2e5+10,P=1e9+7; 9 10 inline ll rd(){ 11 ll x=0;char c=getchar();int neg=1; 12 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 13 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 14 return x*neg; 15 } 16 17 int N,l[maxn],r[maxn],a[maxn],ori[maxn]; 18 int stk[maxn],sh,rnk[maxn],tr[2][maxn]; 19 pa tmp[maxn]; 20 struct Node{ 21 int f,l,r; 22 }nd[maxn]; 23 vector<int> pos[maxn]; 24 int ans,c3[maxn]; 25 bool flag[maxn]; 26 27 28 inline int lowbit(int x){return x&(-x);} 29 inline void add(int i,int x,int y){ 30 for(;x<=N;x+=lowbit(x)) tr[i][x]+=y,tr[i][x]%=P; 31 } 32 inline int query(int i,int x){ 33 int re=0;for(;x;x-=lowbit(x)) re+=tr[i][x],re%=P;return re; 34 } 35 36 inline int getf(int x){return x==nd[x].f?x:nd[x].f=getf(nd[x].f);} 37 38 inline void change(int l,int r,int d){ 39 int n=1ll*(r-l+1)*(r-l+2)/2%P; 40 add(0,l,d*n),add(1,r,d*n); 41 } 42 43 inline void uni(int x){ 44 flag[x]=1;nd[x].l=nd[x].r=x; 45 int a=0,b=0; 46 if(flag[x-1]) a=getf(x-1); 47 if(flag[x+1]) b=getf(x+1); 48 if(a){ 49 nd[a].f=x; 50 change(nd[a].l,nd[a].r,-1); 51 nd[x].l=nd[a].l; 52 }if(b){ 53 nd[b].f=x; 54 change(nd[b].l,nd[b].r,-1); 55 nd[x].r=nd[b].r; 56 } 57 change(nd[x].l,nd[x].r,1); 58 } 59 60 int main(){ 61 //freopen("","r",stdin); 62 int i,j,k; 63 N=rd(); 64 c3[2]=1; 65 for(i=3;i<=N;i++) c3[i]=(c3[i-1]+1ll*i*(i-1)/2)%P; 66 for(i=1;i<=N;i++) ori[i]=a[i]=rd(),tmp[i]=MP(a[i],i),r[i]=N,l[i]=1; 67 sort(tmp+1,tmp+N+1); 68 for(i=1;i<=N;i++) 69 a[i]=lower_bound(tmp+1,tmp+N,MP(a[i],i))-tmp,pos[a[i]].push_back(i); 70 for(i=1;i<=N;i++) nd[i].f=i; 71 72 for(i=N;i;i--){ 73 int x=tmp[i].second; 74 uni(x); 75 int f=getf(x),l=nd[f].l,r=nd[f].r; 76 ans+=1ll*(x-l+1)*(c3[r-x+1]+1ll*(r-x+1)*(query(0,N)-query(0,r+1))%P)%P*ori[x]%P,ans%=P; 77 ans+=1ll*(r-x+1)*(c3[x-l+1]+1ll*(x-l+1)*query(1,l-1)%P)%P*ori[x]%P,ans%=P; 78 } 79 80 printf("%d\n",(ans+P)%P); 81 return 0; 82 }