#include<bits/stdc++.h>
using namespace std;
const long long maxn=200100;
const long long md=1e9+7;
#define mid ((l+r)>>1)
long long n;
long long a[maxn];
vector<int> vec[maxn];
long long tr1[maxn<<2],tr2[maxn<<2];
long long cnt[maxn<<2],tg[maxn<<2];
long long f[maxn],mtg[maxn<<2];
void Add_to(long long h,long long v){
	(tg[h]+=v)%=md;
	tr2[h]=(tr2[h]+tr1[h]*v)%md;
}
void Mult(long long h,long long v){
	mtg[h]=mtg[h]*v%md;
	tr1[h]=tr1[h]*v%md;
	tr2[h]=tr2[h]*v%md;
}
void push_down(long long h){
	if(tg[h]){
		Add_to(h<<1,tg[h]);
		Add_to(h<<1|1,tg[h]);
		tg[h]=0;
	}
	if(mtg[h]!=1){
		Mult(h<<1,mtg[h]);
		Mult(h<<1|1,mtg[h]);
		mtg[h]=1;
	}
}
void push_up(long long h){
	cnt[h]=(cnt[h<<1]+cnt[h<<1|1])%md;
	tr1[h]=(tr1[h<<1]+tr1[h<<1|1])%md;
	tr2[h]=(tr2[h<<1]+tr2[h<<1|1])%md;
}
void Add_to(long long h,long long l,long long r,long long s,long long t){
	if(s<=l&&r<=t){
		Add_to(h,1);
		return;
	}
	push_down(h);
	if(t<=mid)
		Add_to(h<<1,l,mid,s,t);
	else if(s>mid)
		Add_to(h<<1|1,mid+1,r,s,t);
	else{
		Add_to(h<<1,l,mid,s,mid);
		Add_to(h<<1|1,mid+1,r,s,t);
	}
	push_up(h);
}
void Insert(long long h,long long l,long long r,long long p,long long s1,long long s2){
	if(l==r){
		tr1[h]=s1,tr2[h]=s2;
		cnt[h]=1;
		return;
	}
	push_down(h);
	if(p<=mid) Insert(h<<1,l,mid,p,s1,s2);
	else Insert(h<<1|1,mid+1,r,p,s1,s2);
	push_up(h);
}
long long Query_cnt(long long h,long long l,long long r,long long s,long long t){
	if(s<=l&&r<=t) return cnt[h];
	push_down(h);
	if(t<=mid) return Query_cnt(h<<1,l,mid,s,t);
	else if(s>mid) return Query_cnt(h<<1|1,mid+1,r,s,t);
	else
		return (Query_cnt(h<<1,l,mid,s,mid)+Query_cnt(h<<1|1,mid+1,r,mid+1,t))%md;
}
long long Query1(long long h,long long l,long long r,long long s,long long t){
	if(s<=l&&r<=t) return tr1[h];
	push_down(h);
	if(t<=mid) return Query1(h<<1,l,mid,s,t);
	else if(s>mid) return Query1(h<<1|1,mid+1,r,s,t);
	else
		return (Query1(h<<1,l,mid,s,mid)+Query1(h<<1|1,mid+1,r,mid+1,t))%md;
}
long long Query2(long long h,long long l,long long r,long long s,long long t){
	if(s<=l&&r<=t) return tr2[h];
	push_down(h);
	if(t<=mid) return Query2(h<<1,l,mid,s,t);
	else if(s>mid) return Query2(h<<1|1,mid+1,r,s,t);
	else
		return (Query2(h<<1,l,mid,s,mid)+Query2(h<<1|1,mid+1,r,mid+1,t))%md;
}
void Build_tree(long long h,long long l,long long r){
	mtg[h]=1;
	if(l==r) return;
	Build_tree(h<<1,l,mid);
	Build_tree(h<<1|1,mid+1,r);
}
int main(){
	scanf("%lld",&n);
	for(long long i=1;i<=n;i++){
		scanf("%lld",&a[i]);
		vec[a[i]].push_back(i);
	}
	Build_tree(1,1,n);
	long long sum0=1,sum2=0;
	long long siz=0;
	for(long long i=n;i>=1;i--){
		sum2=(sum2+vec[i].size()*(long long)(vec[i].size()-1)/2%md*sum0%md)%md;
		sum2=(sum2+vec[i].size()*Query1(1,1,n,1,n))%md;
		for(vector<int>::iterator it=vec[i].begin();it!=vec[i].end();it++)
			Add_to(1,1,n,*it,n);
		for(vector<int>::iterator it=vec[i].begin();it!=vec[i].end();it++)
			Insert(1,1,n,*it,sum0,sum0*Query_cnt(1,1,n,1,*it)%md);
		siz+=vec[i].size();
		f[i]=(Query2(1,1,n,1,n)-sum2+md+f[i+1]*(siz-(n-i)))%md;
		if(siz-(n-i)-2<0) sum2=0;
		else sum2=sum2*(siz-(n-i)-2)%md;
		sum0=sum0*(siz-(n-i))%md;
		Mult(1,siz-(n-i)-1);
	}
	printf("%lld\n",f[1]);
	return 0;
}
