解方程

Equation

Input file: eqution.in

Output file: eqution.out

Time limit: 1 second

Memory limit: 256 MB

Mr. Ding 又来让你帮忙解方程了。
方程是这样的:
x1 + x1 + x3 +.....+ xn = m (xi >= 0 任意1<= i <= n)
Mr. Ding 希望你求出这个n 元一次方程的整数解有多少个,因为解的个数有可能变得很大,所以Mr.
Ding 只需要你输出解的个数取模于mod。
Input
第1 行,包含一个整数:T,表示询问个数
接下来T 行,每行包含三个整数:n m mod
Output
输出T 行,每行输出解的个数模对应mod
Sample
eqution.in

1

2   3   13
equation.out

4
Note
样例中,解分别是:(3; 0); (2; 1); (1; 2); (0; 3)
• 对于30% 的数据,1 <= n ; m <= 6,mod = 10^8 + 7,T = 1
• 对于70% 的数据,1 <= n ; m <= 10^3,n + m <= mod <= 10^8 + 7,mod 是一个素数,1 <= T <= 100
• 对于余下30% 的数据,1 <= n ; m <= 10^3,n+m <= p ; q <= 10^4,mod = pq,p ; q 是素数,1 <= T <= 10^3

#include<stdio.h>
const int MAXN=1e3*2;
long long fac[MAXN+5],vfac[MAXN+5];


long long n,m,mod;

void exgcd(long long a,long long b,long long &x,long long &y){
    if(b==0) {x=1;y=0;return;}
    exgcd(b,a%b,y,x);
    y-=(a/b)*x;
}

long long rv(long long a,long long p){
    long long x,y;
    exgcd(a,p,x,y);
    return (x%p+p)%p;
}

void init(){
    fac[0]=1;//0的阶乘为1
    for(long long i=1;i<=n+m-1;i++)  fac[i]=fac[i-1]*i%mod;
    vfac[m]=rv(fac[m],mod);//求i的阶乘在mod意义下的逆
    vfac[n-1]=rv(fac[n-1],mod);
}


int main(){
    freopen("equation.in","r",stdin);
    freopen("equation.out","w",stdout);
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%I64d%I64d%I64d",&n,&m,&mod);
        init();
        long long ans=fac[m+n-1]*vfac[m]%mod*vfac[n-1]%mod;
        printf("%I64d
",ans);
    }
}
原文地址:https://www.cnblogs.com/ganster/p/8455709.html