礼物 [Bzoj 2142]

来源:互联网 发布:大数据应用培训课程 编辑:程序博客网 时间:2024/05/16 06:14

题目地址请点击——


礼物


Description

一年一度的圣诞节快要来到了。
每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物。
不同的人物在小E心目中的重要性不同,在小E心中分量越重的人,收到的礼物会越多。
小E从商店中购买了 n 件礼物,打算送给 m 个人,其中送给第 i 个人礼物数量为 wi
请你帮忙计算出送礼物的方案数(两个方案被认为是不同的,当且仅当存在某个人在这两种方案中收到的礼物不同)。
由于方案数可能会很大,你只需要输出模 P 后的结果。


Input

输入的第一行包含一个正整数 P,表示模;
第二行包含两个整整数 nm,分别表示小E从商店购买的礼物数和接受礼物的人数;
以下 m 行每行仅包含一个正整数 wi,表示小E要送给第 i 个人的礼物数量。


Output

若不存在可行方案,则输出“Impossible”,否则输出一个整数,表示模 P 后的方案数。


Sample Input

100 4 2 1 2


Sample Output

12


Hint

【样例说明】

下面是对样例1的说明。

以“/”分割,“/”前后分别表示送给第一个人和第二个人的礼物编号。12种方案详情如下:

1/23 1/24 1/34

2/13 2/14 2/34

3/12 3/14 3/24

4/12 4/13 4/23

【数据规模和约定】

P=pc11pc22pc33pcttpi 为质数。

对于 100% 的数据,1n1091m51pcii105


Solution

si=i1j=1wj,则

ans=i=1mCwinsi mod p

所以我们只要求出 Cyx mod p 的值就可以了。

由CRT,我们只需求出 Cyx mod pji,然后CRT合并即可。

Cyx=x!y!(xy)!

所以只要求出 n! mod pji,就万事大吉了。

n! mod pji=1×2×3××(n1)×n mod pji=[1×2×3××(pi1)×(pi+1)×(pi+2)××(2pi1)×(2pi+1)××n×][pi×2pi× mod pij]


1×2×3××(pji1)(pji+1)×(pji+2)××(2pji1)    (mod pji)

所以左边可以用 1×2×3××(pji1) 的幂加上暴力就可以求了。
右边的话提出一个 pi 就可以递归处理了。

最后将 Cyx 化成 apkibpli 的形式,就可以求出模值了。


Code

#include <iostream>#include <cstdio>#include <cmath>#define LL long long#define MAXN 100000using namespace std;LL p,n,m,ans;LL w[20],s[20];LL pi[1000010],pc[1000010],cc[1000010];LL tmp[1000010];LL pop[1000010];LL tott[1000010];LL returnthing;LL power(LL x,LL y,LL Mod){    if(y==0)return 1;    if(y==1)return x%Mod;    LL tmps=power(x,y/2,Mod);    tmps=tmps*tmps%Mod;    if(y&1)tmps=tmps*(x%Mod)%Mod;    return tmps;}LL jie(LL x,LL i){    if(x==0){returnthing=0;return 1;}    if(x==1){returnthing=0;return 1;}    LL A=x/pc[i],B=x%pc[i];    LL b1=power(tmp[i],A,pc[i])%pc[i];//  LL c1=A*(tott[i]+1);    LL c1=A*pc[i]/pi[i];    for(LL j=A*pc[i]+1;j<=x;j++){        if(j%pi[i]!=0)b1=b1*j%pc[i];        else{            LL ttt=j,tttottt=0;            while(ttt%pi[i]==0){ttt/=pi[i];tttottt++;}            c1+=tttottt;            b1=b1*ttt%pc[i];        }    }    b1=b1*jie(A*pc[i]/pi[i],i)%pc[i];    c1+=returnthing;    returnthing=c1;    return b1;}LL ex_gcd(LL x,LL y,LL &a,LL &b){    if(y==0){a=1;b=0;return x;}    LL ta,tb;    LL z=ex_gcd(y,x%y,ta,tb);    a=tb;b=ta-tb*(x/y);    return z;}LL work(LL x,LL y){    if(x<y||y==0)return 0;    LL now=0;    for(LL i=1;i<=pi[0];i++){        LL f;        LL A=x/pc[i],B=x%pc[i];        LL b1=power(tmp[i],A,pc[i])%pc[i];//      LL c1=A*(tott[i]+1);        LL c1=A*pc[i]/pi[i];        for(LL j=A*pc[i]+1;j<=x;j++){            if(j%pi[i]!=0)b1=b1*j%pc[i];            else{                LL ttt=j,tttottt=0;                while(ttt%pi[i]==0){ttt/=pi[i];tttottt++;}                c1+=tttottt;                b1=b1*ttt%pc[i];            }        }        b1=b1*jie(A*pc[i]/pi[i],i)%pc[i];        c1+=returnthing;        A=(x-y)/pc[i],B=(x-y)%pc[i];        LL b2=power(tmp[i],A,pc[i])%pc[i];//      LL c2=A*(tott[i]+1);        LL c2=A*pc[i]/pi[i];        for(LL j=A*pc[i]+1;j<=x-y;j++){            if(j%pi[i]!=0)b2=b2*j%pc[i];            else{                LL ttt=j,tttottt=0;                while(ttt%pi[i]==0){ttt/=pi[i];tttottt++;}                c2+=tttottt;                b2=b2*ttt%pc[i];            }        }        b2=b2*jie(A*pc[i]/pi[i],i)%pc[i];        c2+=returnthing;        A=y/pc[i],B=y%pc[i];        LL b3=power(tmp[i],A,pc[i])%pc[i];//      LL c3=A*(tott[i]+1);        LL c3=A*pc[i]/pi[i];        for(LL j=A*pc[i]+1;j<=y;j++){            if(j%pi[i]!=0)b3=b3*j%pc[i];            else{                LL ttt=j,tttottt=0;                while(ttt%pi[i]==0){ttt/=pi[i];tttottt++;}                c3+=tttottt;                b3=b3*ttt%pc[i];            }        }        b3=b3*jie(A*pc[i]/pi[i],i)%pc[i];        c3+=returnthing;        LL xxxx,yyyy;        LL ni;        ex_gcd(b2*b3%pc[i],pc[i],xxxx,yyyy);        ni=(xxxx%pc[i]+pc[i])%pc[i];        LL rc=c1-c2-c3;        if(rc>=cc[i])f=0;        else f=b1*ni%pc[i]*power(pi[i],rc,pc[i])%pc[i];        now=(now+(p/pc[i])*pop[i]%p*f%p)%p;    }    return now%p;}void pyh(LL x){    LL tmps=x,sqr=sqrt(x);    for(LL i=2;i<=sqr;i++){        if(tmps%i==0){            pc[++pc[0]]=1;pi[++pi[0]]=i;            while(tmps%i==0){                cc[pc[0]]++;                pc[pc[0]]*=i;                tmps/=i;            }        }    }    if(tmps!=1){cc[++pc[0]]=1;pi[++pi[0]]=tmps;pc[pc[0]]=tmps;}}int main(){    scanf("%lld%lld%lld",&p,&n,&m);    for(LL i=1;i<=m;i++)scanf("%lld",&w[i]);    pyh(p);    for(LL i=1;i<=pc[0];i++){        tmp[i]=1;        for(LL j=1;j<pc[i];j++){            if(j%pi[i]==0){tott[i]++;continue;}            tmp[i]=tmp[i]*j%pc[i];        }    }    for(LL i=1;i<=pi[0];i++){        LL xxxx,yyyy;        ex_gcd(p/pc[i],pc[i],xxxx,yyyy);        pop[i]=(xxxx%pc[i]+pc[i])%pc[i];    }    for(LL i=1;i<=m;i++)s[i]=s[i-1]+w[i];    ans=1;    for(LL i=1;i<=m;i++)        ans=ans*work(n-s[i-1],w[i])%p;    if(ans==0)printf("Impossible\n");    else printf("%lld\n",ans);    return 0;}
1 0
原创粉丝点击