如果WA on 1
查看原帖
如果WA on 1
826079
Autumn_Rain楼主2024/12/7 11:36

样例测不出来的,你可能是和我一样偷懒写了下面这种快速幂。精度问题。

#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;
}
2024/12/7 11:36
加载中...