CF396D
题意
先处理小于的情况,显然可以枚举前
那么逆序对的方案数就分四块了.
令
令
最后不要忘记是不超过,可以等于,记得计算下原序列的逆序对数量.
code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5;
const int mod=1e9+7;
int p[N],n;
ll c[N],f[N];
int lowbit(int u)
{
return u&(-u);
}
void add(int u,int val)
{
while(u<=n)
{
c[u]+=val;
u+=lowbit(u);
}
}
int query(int u)
{
int res=0;
while(u)
{
res+=c[u];
u-=lowbit(u);
}
return res;
}
ll cnt(ll num)
{
return (num*(num-1)/2%mod)*(num*(num-1)/2%mod)%mod*f[num-2]%mod;
}
void run()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&p[i]);
f[0]=1;
for(int i=1;i<=n;i++)
f[i]=f[i-1]*i%mod;
ll ans=0,sum=0;
for(int i=1;i<=n;i++)
{
ll num=p[i]-1-query(p[i]);
ans+=num;ans%=mod;
ans+=num*cnt(n-i)%mod;ans%=mod;
ans+=(num*(num-1)/2%mod)*f[n-i]%mod;ans%=mod;
ans+=sum*num%mod*f[n-i]%mod;
add(p[i],1);
sum+=num;
}
printf("%lld\n",ans);
}
int main()
{
int T=1;
while(T--) run();
return 0;
}