zoukankan      html  css  js  c++  java
  • Codeforces913F. Strongly Connected Tournament

    n<=2000个人参加比赛,这样比:(这里的序号没按题目的)1、两两比一场,比完连个图,边i->j表示i赢了j。2、连完那个图强联通分量缩起来,强连通分量内继续比,即强连通分量递归进行1、2,直到每个强连通分量大小为1.i<j时i有a/b的概率赢j,问每个人比赛的场数的总和的期望,答案%998244353。

    n个人搞完一次会有大大小小的联通块,就可以递归下去了!但是每次可能分出很多种情况,怎么算呢?选他的一个每种图一定有的强连通分量来枚举即可,那就枚举拓扑序最后的那一个分量,也就是输给了除分量外所有人的那些人组成的,吧!$Ans_i$--i个人答案,$Ans_i=sum_{j=1}^{i}str_j*cp_{i,j}*(frac{j(j-1)}{2}+j(i-j)+Ans_i+Ans_{s-i})$,其中$str_i$表示i个点成强连通分量的概率,$cp_{i,j}$表示i个点中j个点输给其他所有人这件事发生的概率。注意到$Ans_i$在$j=i$时会转移到自己,移个项除个系数即可,略。而$str_i=1-sum_{j=1}^{i-1}str_j*cp_{i,j}$,$cp_{i,j}=cp_{i-1,j-1}p^{i-j}+cp_{i-1,j}(1-p)^j,cp_{i,0}=1$。

     1 #include<string.h>
     2 #include<stdlib.h>
     3 #include<stdio.h>
     4 //#include<assert.h>
     5 #include<algorithm>
     6 //#include<iostream>
     7 using namespace std;
     8 
     9 int n,a,b,p;
    10 #define maxn 2011
    11 const int mod=998244353;
    12 int cp[maxn][maxn],str[maxn],ans[maxn];
    13 
    14 int powmod(int a,int b)
    15 {
    16     int ans=1;
    17     while (b)
    18     {
    19         if (b&1) ans=1ll*ans*a%mod;
    20         a=1ll*a*a%mod;
    21         b>>=1;
    22     }
    23     return ans;
    24 }
    25 
    26 int list1p[maxn],listp[maxn];
    27 int main()
    28 {
    29     scanf("%d%d%d",&n,&a,&b); p=1ll*a*powmod(b,mod-2)%mod;
    30     cp[0][0]=1;
    31     list1p[0]=1; for (int i=1;i<=n;i++) list1p[i]=list1p[i-1]*1ll*(mod+1-p)%mod;
    32     listp[0]=1; for (int i=1;i<=n;i++) listp[i]=listp[i-1]*1ll*p%mod;
    33     for (int i=1;i<=n;i++)
    34     {
    35         cp[i][0]=1;
    36         for (int j=1;j<=i;j++) cp[i][j]=list1p[j]*1ll*cp[i-1][j]%mod+listp[i-j]*1ll*cp[i-1][j-1]%mod,
    37         cp[i][j]-=cp[i][j]>=mod?mod:0;
    38     }
    39     str[1]=1;
    40     for (int i=2;i<=n;i++)
    41     {
    42         str[i]=1;
    43         for (int j=1;j<i;j++) str[i]-=str[j]*1ll*cp[i][j]%mod,str[i]+=str[i]<0?mod:0;
    44     }
    45     ans[0]=ans[1]=0;
    46     for (int i=2;i<=n;i++)
    47     {
    48         ans[i]=(str[i]*1ll*cp[i][i]%mod)*i*(i-1)%mod*((mod+1)>>1)%mod;
    49         for (int j=1;j<i;j++) ans[i]+=str[j]*1ll*cp[i][j]%mod*(1ll*j*(j-1)%mod*((mod+1)>>1)%mod
    50         +1ll*j*(i-j)%mod+ans[j]+ans[i-j])%mod,ans[i]-=ans[i]>=mod?mod:0;
    51         ans[i]=1ll*ans[i]*powmod(mod+1-str[i]*1ll*cp[i][i],mod-2)%mod;
    52     }
    53     printf("%d
    ",ans[n]);
    54     return 0;
    55 }
    View Code
  • 相关阅读:
    <海量数据库解决方案>2011041201
    <海量数据库解决方案>2011040801
    <汇编语言(第2版)>2011041701
    makefile实践三为多目录源文件建立makefile
    <海量数据库解决方案>2011042501
    <海量数据库解决方案>2011041101
    <海量数据库解决方案>2011042901
    <海量数据库解决方案>2011042601
    <海量数据库解决方案>2011050301
    <iPhone开发秘籍>温度转换器实践
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8253849.html
Copyright © 2011-2022 走看看