隔板法+费马小定理+逆元+Chino with Equation+2019西北工业大学程序设计创新实践基地春季选拔赛(重现赛)D

链接:https://ac.nowcoder.com/acm/contest/553/D
来源:牛客网

题目描述
Chino的数学很差,因此Cocoa非常担心。今天,Cocoa要教Chino解不定方程。
众所周知,不定方程的解有0个或者若干个。
给出方程:

Cocoa想知道这个不定方程的正整数解和非负整数解各有几个。
题目对Chino来说太难啦,你能帮一帮Chino吗?

输入描述:
两个正整数m, n
输出描述:
题目要求的答案,即正整数解的个数和非负整数解的个数 。由于答案可能会很大,你只需要输出答案 mod(109 + 7) 即可。

示例1
输入
复制
4 7
输出
复制
20 120

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const long long mod =  1e9+7;
int n,m;

ll mul(ll a,ll b,ll c ){
    ll res=0;
    // a%=c;
    while(b){
        if(b&1){
            res=(res+a)%c;
        }
        a=(a+a)%c;
        b>>=1;
    }
    return res;
}
// a^b%c   快速幂+快速乘
ll qc(ll a,ll b,ll c){
    ll res=1;
    // a%=c;
    while(b){
        if(b&1){
            res = mul(res,a,c);
        }
        a = mul(a,a,c);
        b>>=1;
    }
    return res;
}

int main(){
    cin>>m>>n;
    ll sum1 = 1;
    ll sum3 = 1;   
    ll sum2 = 1;

    //排列组合
    for(int i = 1; i <=m-1; i++) {
        sum1=(sum1 * (n+m-i))%mod;
        sum3=(sum3 * (n-i))%mod;
        sum2=(sum2*i)%mod;
    }

    printf("%lld %lld\n",(sum3*qc(sum2,mod-2,mod))%mod,sum1*qc(sum2,mod-2,mod)%mod);
    return 0;
}


隔板法
1.
正整数解的个数的情况
隔板法就是在n个元素间插入(m-1)个板,即把n个元素分成b组的方法。
C(n-1,m-1)

隔板法必须满足三个条件:

这n个元素必须相同,(2)所分成的每一组至少分得一个元素,(3)分成的组别彼此差异。
例如:某校组建一球队需16人,该校共10个班级,且每个班至少分配一个名额,共有几种情况。C(16-1,10-1)。

2.
非负整数解
对n件相同物品(或名额)分给m个人(或位置),允许若干个人(或位置)为空的问题,可以看成将这n件物品分成m组,允许若干组为的问题.将n件物品分成m组,需要m-1块隔板,将这n件物品和m-1块隔板排成一排,占n+m-1位置,从这n+m-1个位置中选m-1个位置放隔板,因隔板无差别,故隔板之间无序,是组合问题,故隔板有**C(n+m-1,m-1)**种不同的方法,再将物品放入其余位置,因物品相同无差别,故物品之间无顺序,是组合问题,只有1种放法,根据分步计数原理,共有
C(n+m-1, m-1×1)=**C(n+m-1,m-1)**种排法

3.
求方程x1+x2+…+xk=n的非负整数解或正整数解

(1)方程x1+x2+x3+x4=10的正整数解有多少组?(m==4的情况)

(2)方程x1+x2+x3+x4=10的非负整数解有多少组?

解:(1)转化为10个相同的小球装入4个不同的盒子,每盒至少有一个,有C(10-1,4-1)=84种。

转化为10个相同的小球装入4个不同的盒子,可以有空盒,有C(10+4-1,4-1)种。
4.求方程x1+x2+…+xm=k(0<=xi<=n)的非负整数解的方案数。

解:有限制条件,用容斥搞一搞。

对于指定t个盒子(例如1,2,3,···,t号盒子)中的球数至少为N+1个球的方法等同于将(X-t*(N+1))个球放入Y个盒中,每个盒中至少0个球的放法,即(X-t*(N+1))个球放入Y个盒子,再在指定的t个盒中放入N个,为C(X-t*(N+1)+Y-1,Y-1)。

根据容斥原理,每个盒子至多N个球的方法为总数-所有指定一个盒子的球数大于N的方法+所有指定两个盒子的球数大于N的方法-所有三个盒子的球数大于N的方法+

即为C(k+m-1,m-1)-C(m,1)C(k-(n+1)+m-1,m-1)+C(m,2)C(k-2(n+1)+m-1,m-1)+···+(-1)^tC(m,t)C(k-t(N+1)+m-1,m-1)+···

其中t属于1到k/(N+1)的闭区间。C(k-t*(N+1)+m-1,m-1)的k-t*(N+1)+m-1>=m-1,一化简就可得到k/(N+1)。


因为涉及到除法取模需要用到费马小定理+逆元
(a/b)%m = a / b * (b*b^(m-2)) = (a * (b^(m-2)))%m;

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值