题意:给出一个数n。接下来n个数,从1到n。其中有些数被-1取代。现在让你求所有情况的逆序对的期望值。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
ll arr[200010],ans;
ll a[200010],b[200010],top,num[200010];
ll qpow(ll a,ll b,ll mod){
ll ans=1;
while(b){
if(b&1){
ans=(ans*a)%mod;
}
a=(a*a)%mod;
b>>=1;
}
return ans;
}
void merge_sort(int l,int r)
{
if(l>=r)
return;
int mid=(l+r)/2,i,j,k;
i=l;k=l;j=mid+1;
merge_sort(l,mid);
merge_sort(mid+1,r);
while(i<=mid && j<=r)
{
if(a[i]<=a[j])
b[k++]=a[i++];
else{
ans+=(ll)(mid-i+1);
ans%=mod;
b[k++]=a[j++];
}
}
while(i<=mid)
b[k++]=a[i++];
while(j<=r)
b[k++]=a[j++];
for(int o=l;o<=r;++o)
a[o]=b[o];
}
int main(){
// freopen("in.txt","r",stdin);
int n;
ll total;
scanf("%I64d",&n);
for(int i=0;i<n;i++){
scanf("%I64d",&arr[i]);
if(arr[i]!=-1){
num[arr[i]]=1;
a[top++]=arr[i];
}
}
if(top-1>0)
merge_sort(0,top-1);
for(int i=1;i<=n;i++){
num[i]+=num[i-1];
}
for(ll i=1;i<=n;i++)
num[i]=i-num[i];
total=num[n];
ll q=1,p=0;
for(ll i=2;i<=total;i++){
q*=i;
q%=mod;
}
p+=(ans*q)%mod;
ll temp=1;
for(ll i=2;i<=total-1;i++){
temp*=i;
temp%=mod;
}
p+=((total*(total-1)/2)%mod*q/2);
p%=mod;
ll xx=total;
for(int i=0;i<n;i++){
if(arr[i]==-1){
total--;
}
else{
p+=((num[arr[i]]*total)%mod*temp)%mod+(((xx-num[arr[i]])*(xx-total))%mod*temp)%mod;
p%=mod;
}
}
cout<<(p*qpow(q,mod-2,mod))%mod;
}