太厉害啦
首先做期望题最不能忘记的就是期望的线性性。
所以我们直接将全局逆序对对数拆成两个数其中一个比另一个大的期望(概率),设为 \(f[i][j]\),初值为 \([a_i>b_j]\)。
如果我们修改两个位置 \(x,y\),最直接的修改一定就是令 \(f[x][y]=0.5\)。
那么别的位置呢?
我们发现这会令 \(f[i][x]=f[i][y],f[x][i]=f[y][i]\),而且因为这是一个排列,很明显有 \(f[a][b]+f[b][a]=1\)。
那么我们怎么才能转移 \(f\)?
很容易发现一件事情,转移前的 \(f[i][x]+f[i][y]\) 等于转移后的 \(f[i][x]+f[i][y]\)。
为什么呢?我比两个数大的概率之和,然后交换一下,明显还是不变嘛。
所以有新的 \(f[i][x]=f[i][y]\) 等于原来的 \(\frac {f[i][x]+f[i][y]} 2\)。
于是这样大力转移就好啦。
#include<cstdio>
const int M=1005;
int n,m,a[M];double ans,dp[M][M];
signed main(){
int i,j,x,y;scanf("%d%d",&n,&m);
for(i=1;i<=n;++i)scanf("%d",a+i);
for(i=1;i<=n;++i)for(j=1;j<=n;++j)dp[i][j]=a[i]>a[j];
while(m--){
scanf("%d%d",&x,&y);
for(i=1;i<=n;++i)dp[x][i]=dp[y][i]=.5*(dp[x][i]+dp[y][i]),dp[i][x]=dp[i][y]=1-dp[x][i];dp[x][y]=dp[y][x]=.5;
}
for(i=1;i<=n;++i)for(j=i+1;j<=n;++j)ans+=dp[i][j];printf("%.9lf",ans);
}