B. hat
思路:顯然無論怎麼交換,最終相同概率的個數是不會變等於,即每次交換隻存在兩種概率,而且對於交換,就是相當於概率交換,所以我們可以找到最終那一個唯一的不同的概率的位置,因爲初始化, 若中有,則變爲另一個位置,接下來我們只考慮沒有被看見的交換,顯然在這次操作後的位置有兔子的概率,存在兩種情況,該位置原來有兔子,但沒有交換它,則此時概率爲:
因爲是從個數中選兩個數,則沒有被選中的概率是。
第二種情況,該位置原來沒有兔子,但是與它交換的位置有兔子。
首先被選中的概率是,然後與它交換的位置有兔子的概率是,(位置等可能性),所以概率是
綜上
然後用費馬小定理轉化一下,遞推就行了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5,M=1e6+5,inf=0x3f3f3f3f,mod=998244353;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
ll ksm(ll a,ll n){
ll ans=1;
while(n){
if(n&1) ans=ans*a%mod;
a=a*a%mod;
n>>=1;
}
return ans;
}
struct p{
int id,x,y;
}a[N];
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
int pos=1;
ll ans1=1,ans2=0;
for(int i=1;i<=k;i++){
int id,x,y;
scanf("%d%d%d",&id,&x,&y);
if(x==pos) pos=y;
else if(pos==y) pos=x;
}
ll inv1=ksm(n,mod-2)%mod,inv2=ksm(n-1,mod-2)%mod,x=(n-2)*inv1%mod,y=(2*inv1*inv2)%mod;
for(int i=1;i<=m-k;i++)
{
ans1=(ans1*x)%mod+((1-ans1+mod)%mod)*y%mod,ans1%=mod;
ans2=(ans2*x)%mod+((1-ans2+mod)%mod)*y%mod,ans2%=mod;
}
for(int i=1;i<=n;i++)
if(pos==i) printf("%lld ",ans1);
else printf("%lld ",ans2);
printf("\n");
}
return 0;
}
對於,顯然可以用數學公式求和。
令
。
轉化爲等比數列:
呃大概思路是這樣,但是有很多細節需要注意。。。還是太菜不會寫。