zoukankan      html  css  js  c++  java
  • 【hdu3037】Saving Beans——组合数取模

    题目链接

    题目的大意是求在n棵树上采摘不超过m颗豆子的方案数,要求答案对给定的p取模,同时保证p为质数。

    奉上大神关于这道题的公式的推导及变形:戳这里

    最后就是求C(n+m,m)%p啦~

    这里因为p<=1e5,而n和m又很大,所以应该要用到Lucas定理:

    Lucas(n,m,p)=C(n%p,m%p)*Lucas(n/p,m/p,p),证明有兴趣的自行百度。

    注意要预处理阶乘才不会TLE,因为p是要求读入的所以每组数据都要预处理一次。

    由费马小定理可知b关于p(要求p是质数)的逆元是b^(p-2),所以这里还要写一个快速幂取模求逆元。

    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 typedef long long LL;
     5 using namespace std;
     6 LL n,m,p;
     7 LL jie[100005];
     8 LL read()
     9 {
    10     LL ans=0,f=1;char c=getchar();
    11     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    12     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
    13     return ans*f;
    14 } 
    15 LL kuai(LL a,LL b)
    16 {
    17     LL res=1;
    18     while(b){
    19         if(b&1)res=res*a%p;
    20         a=(a*a)%p;
    21         b>>=1;
    22     }
    23     return res;
    24 }
    25 LL C(LL x,LL y)
    26 {
    27     if(x<y)return 0;
    28     LL ans;
    29     ans=jie[x]*kuai(jie[y],p-2)%p*kuai(jie[x-y],p-2)%p;
    30     return ans;
    31 }
    32 LL lucas(LL x,LL y)
    33 {
    34     LL ans=1;
    35     while(x&&y&&ans){
    36         if(x%p<y%p)return 0;
    37         ans=(ans*C(x%p,y%p))%p;
    38         x/=p;
    39         y/=p;
    40     }
    41     return ans;
    42 }
    43 int main()
    44 {
    45     LL t;
    46     t=read();
    47     while(t--){
    48         n=read();m=read();p=read();
    49         jie[0]=jie[1]=1;
    50         for(int i=2;i<=p;i++)jie[i]=jie[i-1]*i%p;
    51         printf("%lld
    ",lucas(n+m,m));
    52     }
    53     return 0;
    54 }
    hdu3037
  • 相关阅读:
    python中装饰器
    python中函数后面的小括号的作用
    python中闭包
    python中LEGB原则
    python中不能在外层函数以外调用内层函数
    “咏刚的家”全新改版
    四个半月——我离 Google 有多远?
    关于翻译的两篇好文章
    崔健,又见崔健
    第一天——适逢惊蛰
  • 原文地址:https://www.cnblogs.com/JKAI/p/7443428.html
Copyright © 2011-2022 走看看