样例测不出来的,你可能是和我一样偷懒写了下面这种快速幂。精度问题。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=3e3+10;
const ll p=1e9+7;
const ll inv=5e8+4;
int n,q;
int x,y;
ll a[N];
ll f[N][N];
//f[i][j]:a[i]<a[j]的概率
ll res,ans;
ll qpow(ll a,ll b){
ll res=1;
while(b){
if(b&1)res=res*a%p;
b>>=1;
a=a*a%p;
}
return res;
}
void cal(ll &x,ll &y){
x=y=(x+y)*inv%p;
}
int main(){
cin>>n>>q;
// res=qpow(2,q);//总方案数
res=pow(2,q);
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
f[i][j]=(a[i]<a[j]);
//原始概率
}
}
while(q--){
cin>>x>>y;
//总有一半的概率会交换
//交换就产生逆序对 (原:a[x]<a[y] 换:a[x]>a[y])
cal(f[x][y],f[y][x]);
//交换双方的贡献
for(int i=1;i<=n;i++){
if(i==x||i==y){
continue;
}
cal(f[x][i],f[y][i]);
cal(f[i][x],f[i][y]);
//更新对其他点的贡献
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<i;j++){
ans=(ans+f[i][j])%p;
//所有的a[i]<a[j]的概率总和
}
}//最后是贡献之和
cout<<ans*res%p;
return 0;
}