zoukankan      html  css  js  c++  java
  • hdu 3037 Saving Beans (lucas定理)

    考虑加多一颗树,这样的话当加的树放了k(0<=k<=m)个beans时,原本的n颗树上放的beans数量之和就等于m-k(<=m),满足题目的要求 ,也降低了计算的难度。

    则题目要求的是a1+a2+......an+an+1=m(0<=ai<=m,1<=i<=n+1)                                                                                            式1

    解有多少组。

    考虑把问题转换成,求a1+a2+......an+an+1=m+n+1(1<=ai<=m+1,1<=i<=n+1)                                                                        式2

    解有多少组。

    因为式1的每组解,对于每个ai,都加上1的话,就是式2的一组解。

    对于式2的求解:

    考虑有m+n+1个Beans排成一列,则它们中恰好有m+n个间隔,在m+n个间隔中选择n个各插入一块木板,则把这些Beans分成n+1部分,每部分的值对应到每个ai,就是式2的一组解。而在m+n个间隔中选择n个,则是求组合数的问题了,p<=10^5且为质数,则可用Lucas定理求。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    typedef long long ll;
    ll n,m,p;
    
    ll POW(ll x,ll n,ll p){
        ll res=1;
        while(n){
            if(n&1)res=res*x%p;
            n>>=1;
            x=x*x%p;
        }
        return res;
    }
    ll cm(ll n,ll m,ll p){
        ll a=1,b=1;
        while(m){
            a=a*n%p;
            b=b*m%p;
            n--;
            m--;
        }
        return a*POW(b,p-2,p)%p;
    }
    ll lucas(ll n,ll m,ll p){
        if(!m)return 1;
        return cm(n%p,m%p,p)*lucas(n/p,m/p,p)%p;
    }
    int main()
    {
    //    freopen("in","r",stdin);
        int T;
        cin>>T;
        while(T--){
            scanf("%I64d%I64d%I64d",&n,&m,&p);
            printf("%I64d
    ",lucas(n+m,n,p));
        }
        return 0;
    }
  • 相关阅读:
    Js获取或计算时间的相关操作
    SqlServer删除表中重复的记录并保留一条
    获取js文件后的参数
    谷歌浏览器官方下载地址
    ionic项目中实现发短信和打电话
    ui-router传递参数
    ng-options用法详解
    html5 localStorage(本地存储)
    cordova插件之Local Notification(本地通知)
    AngularJS $http service
  • 原文地址:https://www.cnblogs.com/wshh/p/3988147.html
Copyright © 2011-2022 走看看