// Author -- Frame

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<iostream>
#include<cassert>

#define lowbit(x) ((x)&(-x))
#define Finline __inline__ __attribute__ ((always_inline))
#define DEBUG fprintf(stderr,"Running on Line %d in Function %s\n",__LINE__,__FUNCTION__)

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;

const int inf=0x3f3f3f3f,Inf=0x7fffffff;
const ll INF=0x7fffffffffffffff;
const double eps=1e-10;

template <typename _Tp>_Tp gcd(const _Tp &a,const _Tp &b){return (!b)?a:gcd(b,a%b);}
template <typename _Tp>Finline _Tp abs(const _Tp &a){return a>=0?a:-a;}
template <typename _Tp>Finline _Tp max(const _Tp &a,const _Tp &b){return a<b?b:a;}
template <typename _Tp>Finline _Tp min(const _Tp &a,const _Tp &b){return a<b?a:b;}
template <typename _Tp>Finline void chmax(_Tp &a,const _Tp &b){(a<b)&&(a=b);}
template <typename _Tp>Finline void chmin(_Tp &a,const _Tp &b){(b<a)&&(a=b);}
template <typename _Tp>Finline bool _cmp(const _Tp &a,const _Tp &b){return abs(a-b)<=eps;}
template <typename _Tp>Finline void read(_Tp &x)
{
	register char ch(getchar());
	bool f(false);
	while(ch<48||ch>57) f|=ch==45,ch=getchar();
	x=ch&15,ch=getchar();
	while(ch>=48&&ch<=57) x=(((x<<2)+x)<<1)+(ch&15),ch=getchar();
	if(f) x=-x;
}
template <typename _Tp,typename... Args>Finline void read(_Tp &t,Args &...args)
{
	read(t);read(args...);
}
Finline int read_str(char *s)
{
	register char ch(getchar());
	while(ch==' '||ch=='\r'||ch=='\n') ch=getchar();
	register char *tar=s;
	*tar=ch,ch=getchar();
	while(ch!=' '&&ch!='\r'&&ch!='\n'&&ch!=EOF) *(++tar)=ch,ch=getchar();
	return tar-s+1;
}

const int N=200005;
const int mod=1000000007;
const int inv2=500000004;
template<typename _Tp1,typename _Tp2>Finline void add(_Tp1 &a,_Tp2 b){(a+=b)>=mod&&(a-=mod);}
template<typename _Tp1,typename _Tp2>Finline void sub(_Tp1 &a,_Tp2 b){(a-=b)<0&&(a+=mod);}
Finline int add_val(int a,int b){return (a+b)>=mod?a+b-mod:a+b;}
ll ksm(ll a,ll b=mod-2)
{
	ll res=1;
	while(b)
	{
		if(b&1) res=res*a%mod;
		a=a*a%mod,b>>=1;
	}
	return res;
}
int a[N],b[N];
std::pair<int,int> c[N];
int pos[N];
int n;
int val[N];
int pre[N],suf[N];
int mul[N],sum[N];
int inv[N];
int init(int *a)
{
	int ans=1;
	pre[0]=1;
	mul[0]=1;
	inv[0]=1;
	for(int i=1;i<=n;++i)
	{
		val[i]=a[i]-i+1;
		if(val[i]<=0)
		{
			printf("0\n");
			exit(0);
		}
		pre[i]=1ll*pre[i-1]*val[i]%mod;
		sum[i]=sum[i-1]+(val[i]==1);
		if(val[i]==1)
		{
			mul[i]=mul[i-1];
			sum[i]=sum[i-1]+1;
		}
		else
		{
			mul[i]=1ll*mul[i-1]*(val[i]-1)%mod;
			sum[i]=sum[i-1];
		}
		inv[i]=ksm(mul[i]);
		ans=1ll*ans*val[i]%mod;
	}
	suf[n+1]=1;
	for(int i=n;i>=1;--i)
	{
		suf[i]=1ll*suf[i+1]*val[i]%mod;
	}
	return ans;
}
struct node{
	int val,cnt;
	Finline void operator += (const node &o)
	{
		add(val,o.val);
		cnt+=o.cnt;
	}
	Finline node operator + (const node &o)const
	{
		return (node){add_val(val,o.val),cnt+o.cnt};
	}
};
struct seg_tr{
	struct Node{
		int ls,rs;
		node val;
	}f[N<<1];
	int node_cnt;
	Finline void PushUp(int x)
	{
		f[x].val=f[f[x].ls].val+f[f[x].rs].val;
	}
	int build(int l,int r)
	{
		int cur=++node_cnt;
		if(l==r)
		{
			return cur;
		}
		int mid=(l+r)>>1;
		f[cur].ls=build(l,mid);
		f[cur].rs=build(mid+1,r);
		PushUp(cur);
		return cur;
	}
	void Update(int pos,int l,int r,int cur,int C)
	{
		if(l==r)
		{
			f[cur].val+=(node){C,1};
			return;
		}
		int mid=(l+r)>>1;
		if(pos<=mid) Update(pos,l,mid,f[cur].ls,C);
		else Update(pos,mid+1,r,f[cur].rs,C);
		PushUp(cur);
	}
	node Query(int L,int R,int l,int r,int cur)
	{
		if(L<=l&&r<=R)
		{
			return f[cur].val;
		}
		int mid=(l+r)>>1;
		if(L<=mid&&R>mid)
		{
			return Query(L,R,l,mid,f[cur].ls)+Query(L,R,mid+1,r,f[cur].rs);
		}
		if(L<=mid)
		{
			return Query(L,R,l,mid,f[cur].ls);
		}
		return Query(L,R,mid+1,r,f[cur].rs);
	}
}tr;
int main()
{
	read(n);
	for(int i=1;i<=n;++i)
	{
		read(a[i]);
		b[i]=a[i];
		c[i]=std::make_pair(a[i],i);
	}
	std::sort(b+1,b+n+1);
	std::sort(c+1,c+n+1);
	for(int i=1;i<=n;++i) pos[c[i].second]=i;
	int tot=init(b);
	int ans=0;
	tr.build(1,n);
	for(int i=n;i>=1;--i)
	{
		int p1=pos[i];
		int l=p1+1,r=n;
		while(l<r)
		{
			int mid=(l+r+1)>>1;
			if(sum[mid-1]==sum[p1]) l=mid;
			else r=mid-1;
		}
		if(p1<l) add(ans,1ll*tr.Query(p1+1,l,1,n,1).val*pre[p1]%mod*max(0,a[i]-p1)%mod*inv[p1]%mod);
		tr.Update(p1,1,n,1,1ll*suf[p1+1]*mul[p1-1]%mod);
	}
	ans=1ll*ans*inv2%mod;
	memset(tr.f,0,sizeof(tr.f));
	tr.node_cnt=0;
	tr.build(1,n);
	for(int i=1;i<=n;++i)
	{
		int p1=pos[i];
		int l=p1+1,r=n;
		while(l<r)
		{
			int mid=(l+r+1)>>1;
			if(sum[mid-1]==sum[p1]) l=mid;
			else r=mid-1;
		}
		node tmp=tr.Query(p1+1,l,1,n,1);
		ll val=1ll*tot*tmp.cnt%mod;
		sub(val,1ll*inv2*pre[p1]%mod*max(0,a[i]-p1)%mod*inv[p1]%mod*tmp.val%mod);
		add(ans,val);
		if(l<n)
		{
			tmp=tr.Query(l+1,n,1,n,1);
			add(ans,1ll*tmp.cnt*tot%mod);
		}
		tr.Update(p1,1,n,1,1ll*suf[p1+1]*mul[p1-1]%mod);
	}
	printf("%d\n",ans);
	/*
	for(int i=1;i<=n;++i)
	{
		for(int j=i+1;j<=n;++j)
		{
			else if(a[i]>a[j])
			{
				int p1=pos[j],p2=pos[i];
				ll val=1ll*pre[p1]*suf[p2+1]%mod*max(0,a[j]-p1)%mod*mul[p2-1]%mod*inv[p1]%mod;
				if(sum[p2-1]!=sum[p1]) val=0;
				val=1ll*val*inv2%mod;
				val=(tot-val+mod)%mod;
				add(ans,val);
			}
		}
	}
	*/
	return 0;
}


Measured memory_bytes: 15104