zoukankan      html  css  js  c++  java
  • CF1096E The Top Scorer

    Link
    枚举自己的分数(i),再枚举有多少人(j)的分数是(i),那么答案就是(sumlimits_{i=r}^ssumlimits_{j=1}^pfrac{f(s-ij,p-j,i){p-1choose j-1}}j),其中(f(n,m,l))是指把(n)个球放进(m)个盒子,每个盒子中的球数必须(<l)的方案数。
    容斥+隔板法得到(f(n,m,l)=sumlimits_{i=0}^m(-1)^i{mchoose i}{n-il+m-1choose m-1})。注意要先判断(f(n,m,l)=0)的情况。

    #include<cstdio>
    const int N=5107,P=998244353;
    int r,p,s,c[N][N],inv[107];
    int mod(int x){return x+(x>>31&P);}
    int inc(int a,int b){return mod(a+b-P);}
    int dec(int a,int b){return mod(a-b);}
    int mul(int a,int b){return 1ll*a*b%P;}
    int pow(int a,int k){int r=1;for(;k;k>>=1,a=mul(a,a))if(k&1)r=mul(a,r);return r;}
    int C(int n,int m){return n<0||m<0||n<m? 0:c[n][m];}
    int f(int n,int m,int l)
    {
        if(!n) return 1;
        int ans=0;
        for(int i=0;i<=m;++i) ans=(i&1? dec:inc)(ans,mul(C(m,i),C(n-i*l+m-1,m-1)));
        return ans;
    }
    int main()
    {
        inv[0]=inv[1]=1,scanf("%d%d%d",&p,&s,&r);int ans=0;
        for(int i=0,j;i<=5100;++i)for(c[i][0]=j=1;j<=i;++j)c[i][j]=inc(c[i-1][j],c[i-1][j-1]);
        for(int i=2;i<=100;++i)inv[i]=mul(inv[P%i],P-P/i);
        for(int i=r;i<=s;++i) for(int j=1;j<=p&&j*i<=s;++j) if(p*i-p+j>=s) ans=inc(ans,mul(mul(inv[j],C(p-1,j-1)),f(s-i*j,p-j,i)));
        printf("%d",mul(ans,pow(C(s-r+p-1,p-1),P-2)));
    }
    
  • 相关阅读:
    使用servicename连接Oracle数据库
    使用SID连接Oracle数据库
    使用xlrd模块
    【Project Euler 8】Largest product in a series
    Git使用帮助
    【Project Euler 1】Multiples of 3 and 5
    VSCode使用新体验
    导出牛顿引力形式为平方反比的两种方式
    NOIP2018游记
    即将退役声明
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12244601.html
Copyright © 2011-2022 走看看