Description
一年一度的圣诞节快要来到了. 每年的圣诞节小 E 都会收到许多礼物, 当然他也会送出许多礼物. 不同的人物在小 E
心目中的重要性不同, 在小 E 心中分量越重的人, 收到的礼物会越多. 小 E 从商店中购买了 n 件礼物, 打算送给 m 个人
, 其中送给第 i 个人礼物数量为 wi. 请你帮忙计算出送礼物的方案数 (两个方案被认为是不同的, 当且仅当存在某
个人在这两种方案中收到的礼物不同). 由于方案数可能会很大, 你只需要输出模 P 后的结果.
Solution
答案就是 \(\Pi_{i=1}^{n} C_{n-\sum_{j=1}^{i-1}w_j}^{w_i}\)
用 \(exlucas\) 求一下就行了, 一些细节写在代码里了
- #include<bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- const int N=1e5+10;
- int Fac[N];ll P,w[10];
- inline ll ksc(ll x,ll k,ll mod){
- ll sum=0;k=(k%mod+mod)%mod;
- while(k){
- if(k&1)sum=(sum+x)%mod;
- x=(x+x)%mod;k>>=1;
- }
- return sum;
- }
- inline int qm(int x,int k,int mod){
- int sum=1;
- while(k){
- if(k&1)sum=1ll*sum*x%mod;
- x=1ll*x*x%mod;k>>=1;
- }
- return sum;
- }
- inline void exgcd(ll a,ll b,ll &x,ll &y){
- if(!b)x=1,y=0;
- else exgcd(b,a%b,y,x),y-=a/b*x;
- }
- inline ll inv(ll a,ll b){
- ll x,y;exgcd(a,b,x,y);
- return (x%b+b)%b;
- }
- inline int fac(int n,int p,int pr){
- if(n<=1)return 1;
- int ret=Fac[pr];
- ret=qm(ret,n/pr,pr);
- ret=1ll*ret*Fac[n%pr]%pr;
- return 1ll*ret*fac(n/p,p,pr)%pr;
- }
- inline ll C(int n,int m,int p,int pr){
- int c=0;
- for(ll i=p;i<=n;i*=p)c+=n/i; //long long !!
- for(ll i=p;i<=m;i*=p)c-=m/i;
- for(ll i=p;i<=n-m;i*=p)c-=(n-m)/i;
- int a=fac(n,p,pr),b=fac(m,p,pr),d=fac(n-m,p,pr);
- int ret=1ll*a*inv(b,pr)%pr*inv(d,pr)%pr*qm(p,c,pr)%pr;
- return ksc(ksc((P/pr),inv(P/pr,pr),P),ret,P); //!!
- }
- inline ll exlucas(int n,int m){
- if(n<m)return 0;
- ll ret=0,x=P;
- for(int i=2;i<=100000;i++)if(x%i==0){
- int p=1;
- while(x%i==0)p*=i,x/=i;
- Fac[0]=1;
- for(int j=1;j<=p;j++)Fac[j]=1ll*Fac[j-1]*(j%i?j:1)%p;
- ret=(ret+C(n,m,i,p))%P;
- }
- if(x>1){
- Fac[0]=1;
- for(int j=1;j<=x;j++)Fac[j]=1ll*Fac[j-1]*(j%x?j:1)%x;
- ret=(ret+C(n,m,x,x))%P;
- }
- return ret;
- }
- int main(){
- freopen("pp.in","r",stdin);
- freopen("pp.out","w",stdout);
- int n,m;ll ans=1,sum=0;
- cin>>P>>n>>m;
- for(int i=1;i<=m;i++)cin>>w[i],sum+=w[i];
- if(sum>n)puts("Impossible"),exit(0);
- for(int i=1;i<=m;i++){
- ans=ksc(ans,exlucas(n,w[i]),P);
- n-=w[i];
- }
- cout<<ans<<endl;
- return 0;
- }
来源: http://www.bubuko.com/infodetail-2570209.html