#include <bits/stdc++.h>
#define gc getchar()
#define root 1,1,n
#define lc cur<<1
#define rc lc|1
#define lson lc,l,mid
#define rson rc,mid+1,r
using namespace std;
typedef long long ll;
const int mod=1000000007;
const int N=200009;
int n,a[N],cnt[N],sum=1,tg[N<<2],Ans,inv2;
vector<int> q[N];
struct node
{
	int sum,num;
	node(int sum=0,int num=0):sum(sum),num(num){}
	friend node operator +(const node &A,const node &B)
	{
		return node((A.sum+B.sum)%mod,A.num+B.num);
	}
}val[N<<2];
int read()
{
	int x=1;
	char ch;
	while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;
	int s=ch-'0';
	while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';
	return s*x;
}
int ksm(int x,int y,int ret=1)
{
	for (;y;y>>=1,x=(ll)x*x%mod)
		if (y&1) ret=(ll)ret*x%mod;
	return ret;
}
void add(int cur,int x)
{
	val[cur].sum=(ll)val[cur].sum*x%mod,tg[cur]=(ll)tg[cur]*x%mod;
}
void down(int cur)
{
	if (tg[cur]==1) return;
	add(lc,tg[cur]),add(rc,tg[cur]);
	tg[cur]=1;
}
void ins(int cur,int l,int r,int x,int y)
{
	if (l==r)
	{
		val[cur]=node(y,1);
		return;
	}
	int mid=(l+r>>1);
	down(cur);
	if (x<=mid) ins(lson,x,y);
	else ins(rson,x,y);
	val[cur]=val[lc]+val[rc];
}
node qry(int cur,int l,int r,int L,int R)
{
	if (L<=l&&R>=r) return val[cur];
	int mid=(l+r>>1);
	down(cur);
	node ret=node(0,0);
	if (L<=mid) ret=ret+qry(lson,L,R);
	if (R>mid) ret=ret+qry(rson,L,R);
	return ret;
}
int main()
{
	inv2=(mod+1)/2;
	n=read();
	for (int i=1;i<=n;i++) cnt[a[i]=read()]++,q[a[i]].push_back(i);
	for (int i=n-1;i;i--) cnt[i]+=cnt[i+1];
	for (int i=1;i<=n;i++)
	{
		cnt[i]-=n-i;
		if (cnt[i]<=0)
		{
			puts("0");
			return 0;
		}
		sum=(ll)sum*cnt[i]%mod;
	}
	for (int i=0;i<(N<<2);i++) tg[i]=1;
	for (int i=n;i;i--)
	{
		for (int j:q[i])
		{
			node now=qry(root,j,n);
			Ans=(Ans+(ll)now.sum*inv2)%mod;
			now=qry(root,1,j);
			Ans=(Ans+(ll)now.num*sum%mod-(ll)now.sum*inv2%mod+mod)%mod;
		}
		int sz=q[i].size();
		Ans=(Ans+(ll)sz*(sz-1)/2%mod*sum%mod*inv2%mod)%mod;
		for (int j:q[i]) ins(root,j,sum);
		add(1,(ll)(cnt[i]-1)*ksm(cnt[i],mod-2)%mod);
	}
	printf("%d\n",Ans);
	return 0;
}
