Luo Ying original Green Valley P5520 (combinatorics)

First, the trees no more than three cases: two trees, one answer, no two trees. Three cases independently of each other, where only discuss two trees circumstances.

Without considering the order of the tree, the method according to the interposer The Reduction of the following: $ nm $ vacancies to arrange $ m-1 $ intervals, the interval required for each non-empty. $ $ Nm i.e. the element divided into a number $ m-1 $ embodiment nonempty segments. Then the answer is found a method interposer $ C ^ {m-2} _ {nm-1} $.

Similarly available answers to the other two cases. Were combined to give the final answer: $ (C ^ {m-2} _ {nm-1} + 2C ^ {m-1} _ {nm-1} + C ^ m_ {nm-1}) \ times m $ (! there is a tree there are about two possibilities)

Because they did not think about points can be used directly on the prime factor decomposition hard to do

#include<cstdio>
#include<cstring>
typedef long long ll;
int p[50],pcnt=0,mod;
void exgcd(int a,int b ,int &x,int &y){
    if(!b){x=1;y=0;}
    else{
        exgcd(b,a%b,y,x);
        y-=a/b*x;
    }
}
inline int inv(int a){
    int x,y;
    exgcd(a,mod,x,y);
    return x<0?x+mod:x;
}
inline int fp(int a,int p){
    int s=1;
    while(p){
        if(p&1)s=(ll)s*a%mod;
        a=(ll)a*a%mod;
        p>>=1;
    }
    return s;
}
struct node{
    int a,k[50];
    inline void operator *=(int x){
        for(int i=1;i<=pcnt;++i)
            while(!(x%p[i])){++k[i];x/=p[i];}
        a=(ll)a*x%mod;
    }
    inline void operator /=(int x){
        for(int i=1;i<=pcnt;++i)
            while(!(x%p[i])){--k[i];x/=p[i];}
        a=(ll)a*inv(x)%mod;
    }
}s;
inline void work(int mod){
    for(int i=2;i*i<=mod;++i)if(!(mod%i)){
        p[++pcnt]=i;
        while(!(mod%i))mod/=i;
    }
    if(mod>1)p[++pcnt]=mod;
}
inline int C(int n,int m){
    if(n<m)return 0;
    int i,ans=1;
    s.a=1;memset(s.k,0,sizeof(s.k));
    for(i=0;i<m;++i)s*=n-i;
    for(i=2;i<=m;++i)s/=i;
    ans=s.a;
    for(i=1;i<=pcnt;++i)ans=(ll)ans*fp(p[i],s.k[i])%mod;
    return ans;
}
int main(){
    int n,m,i,ans;
    scanf("%d%d%d%d",&i,&n,&m,&mod);
    if(mod==1){
        puts("0");
        return 0;
    }
    if(m==1){
        printf("%d\n",n%mod);
        return 0;
    }
    if(n==1){
        puts("1");
        return 0;
    }
    work(mod);
    ans=((ll)C(n-m-1,m-2)+(C(n-m-1,m-1)<<1)+C(n-m-1,m))%mod;
    for(i=2;i<=m;++i)ans=(ll)ans*i%mod;
    printf("%d",years);
    return  0 ; 
}
View Code

 

Guess you like

Origin www.cnblogs.com/sunshine-chen/p/11412562.html