您的位置:首页 > 其它

[CF913F]Strongly Connected Tournament

2018-01-11 10:21 260 查看

Description

太长了自己看

相信各位打过Hello 2018的dalao都知道题意我就不多讲了。

Solution

这道题比赛时没想真是亏了。。。

首先根据一些竞赛图相关姿势我们知道汉密尔顿回路唯一且一定存在,那么这个条件就没有用了

然后让我们来慢慢套路。

首先设Fn表示n个点的答案,枚举n所在的强联通分量的大小,我们可以得到:F[n]=∑i=1n(F[n−i]+F[i]+i∗(i−1)2+(n−i)∗i)∗G[i]∗Cp[n][i]

G[i]表示i个点内部打成强联通分量的概率

Cp
[i]表示从n个点中输出i个点的概率(输的点之间不互相计算)

接下来考虑G
如何计算,直接计算可能比较麻烦,我们可以考虑容斥,枚举n所在的强联通分量的大小

G[n]=1−∑i=1n−1G[i]∗Cp[n][i]

那么我们只需要考虑如何求解Cp
[m]了,考虑新加入一个点是否被输出来

Cp[n][m]=Cp[n−1][m]∗(1−p)m+Cp[n−1][m−1]∗pn−m

然后这道题就做完了,真是满满的计数题的套路23333

Code

#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;

typedef long long ll;

const int N=2*1e3+5,Mo=998244353;

int pwr(int x,int y) {
int z=1;
for(;y;y>>=1,x=(ll)x*x%Mo)
if (y&1) z=(ll)z*x%Mo;
return z;
}

int n,a,b,p,q,P
,Q
,Cp

,G
,F
;

int main() {
scanf("%d",&n);
scanf("%d%d",&a,&b);
int p=(ll)a*pwr(b,Mo-2)%Mo,q=Mo+1-p;
P[0]=1;fo(i,1,n) P[i]=(ll)P[i-1]*p%Mo;
Q[0]=1;fo(i,1,n) Q[i]=(ll)Q[i-1]*q%Mo;
Cp[0][0]=1;
fo(i,1,n) {
Cp[i][0]=1;
fo(j,1,i) Cp[i][j]=((ll)Cp[i-1][j]*Q[j]%Mo+(ll)Cp[i-1][j-1]*P[i-j]%Mo)%Mo;
}
G[1]=1;
fo(i,2,n) {
G[i]=1;
fo(j,1,i-1) (G[i]+=Mo-(ll)G[j]*Cp[i][j]%Mo)%=Mo;
}
F[1]=0;
fo(i,2,n) {
fo(j,1,i-1) {
int now=0;
(now+=F[i-j]+F[j])%=Mo;
(now+=j*(j-1)/2)%=Mo;
(now+=(i-j)*j)%=Mo;
(F[i]+=(ll)now*G[j]%Mo*Cp[i][j]%Mo)%=Mo;
}
(F[i]+=(ll)i*(i-1)/2*G[i]%Mo*Cp[i][i]%Mo)%=Mo;
F[i]=(ll)F[i]*pwr(1+Mo-(ll)G[i]*Cp[i][i]%Mo,Mo-2)%Mo;
}
printf("%d\n",F
);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: