zoukankan      html  css  js  c++  java
  • 一本通1659礼物

    2142: 礼物

    Description

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

    Input

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

    Output

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

    Sample Input

    100
    4 2
    1
    2

    Sample Output

    12
    【样例说明】
    下面是对样例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=p1^c1 * p2^c2 * p3^c3 * … *pt ^ ct,pi为质数。
    对于100%的数据,1≤n≤109,1≤m≤5,1≤pi^ci≤10^5。
     
    sol:这道题不就是一个ExLucas板子吗,然后码+调了一年
    Ps:我太菜了
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    inline ll read()
    {
        ll s=0;
        bool f=0;
        char ch=' ';
        while(!isdigit(ch))
        {
            f|=(ch=='-'); ch=getchar();
        }
        while(isdigit(ch))
        {
            s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
        }
        return (f)?(-s):(s);
    }
    #define R(x) x=read()
    inline void write(ll x)
    {
        if(x<0)
        {
            putchar('-'); x=-x;
        }
        if(x<10)
        {
            putchar(x+'0'); return;
        }
        write(x/10);
        putchar((x%10)+'0');
        return;
    }
    #define W(x) write(x),putchar(' ')
    #define Wl(x) write(x),putchar('
    ')
    ll n,m,Sum;
    ll Num[10];
    ll cnt=0,Mo[65],Yu[65];
    ll prim[65],T[65];
    
    inline ll Ksm(ll x,ll y,ll Pk);
    inline ll C(ll n,ll m,ll P,ll Pk);
    inline ll Solve();
    inline void Exgcd(ll a,ll b,ll &X,ll &Y);
    inline ll Jiecheng(ll n,ll P,ll Pk);
    inline ll Exlucas(ll n,ll m,ll Mod);
    inline ll Inv(ll Num,ll Mod);
    
    inline ll Ksm(ll x,ll y,ll Pk)
    {
        ll Ans=1;
        while(y)
        {
            if(y&1) Ans=Ans*x%Pk;
            x=x*x%Pk;
            y>>=1;
        }
        return Ans;
    }
    inline void Exgcd(ll a,ll b,ll &X,ll &Y)
    {
        if(b==0)
        {
            X=1;
            Y=0;
            return;
        }
        Exgcd(b,a%b,X,Y);
        ll XX=X,YY=Y;
        X=YY;
        Y=XX-a/b*YY;
        return;
    }
    inline ll Inv(ll Num,ll Mod) //Num*Inv = 1 (%Mod)
    {
        ll a=Num,b=Mod,c=1,X,Y;
        Exgcd(a,b,X=0,Y=0);
        return (X%b+b)%b;
    }
    inline ll Jiecheng(ll n,ll P,ll Pk)
    {
        if(!n) return 1;
        ll i,Ans=1;
        for(i=2;i<=Pk;i++) if(i%P) Ans=Ans*i%Pk;
        Ans=Ksm(Ans,n/Pk,Pk);
        for(i=2;i<=n%Pk;i++) if(i%P) Ans=Ans*i%Pk;
        return Ans*Jiecheng(n/P,P,Pk)%Pk;
    }
    inline ll C(ll n,ll m,ll P,ll Pk)
    {
        ll Jn=Jiecheng(n,P,Pk);
        ll Jm=Jiecheng(m,P,Pk);
        ll Jnm=Jiecheng(n-m,P,Pk);
        ll i,oo=0;
        for(i=n;i;i/=P) oo+=i/P;
        for(i=m;i;i/=P) oo-=i/P;
        for(i=n-m;i;i/=P) oo-=i/P;
        return Jn*Inv(Jm,Pk)%Pk*Inv(Jnm,Pk)%Pk*Ksm(P,oo,Pk)%Pk;
    }
    inline ll Exlucas(ll n,ll m,ll Mod)
    {
        ll i,tmp=Mod;
        cnt=0;
        for(i=2;i<=sqrt(tmp);i++) if(tmp%i==0)
        {
            ll Num=1;
            while(tmp%i==0)
            {
                Num*=i;
                tmp/=i;
            }
            Mo[++cnt]=Num;
            Yu[cnt]=C(n,m,i,Num)%Num;
        }
        if(tmp>1)
        {
            Mo[++cnt]=tmp;
            Yu[cnt]=C(n,m,tmp,tmp)%tmp;
        }
        return Solve();
    }
    inline ll Solve()
    {
        memmove(prim,Mo,sizeof Mo);
        memmove(T,Yu,sizeof T);
        int i;
        ll Lcm=prim[1];
        for(i=2;i<=cnt;i++)
        {
            ll a=prim[i-1],b=prim[i],c=T[i]-T[i-1],r=1,X,Y;
            Exgcd(a,b,X=0,Y=0);
            ll tmp=b/r;
            X=(X*c%tmp+tmp)%tmp;
            prim[i]=Lcm=Lcm*prim[i];
            T[i]=(X*prim[i-1]+T[i-1])%Lcm;
        }
        return T[cnt];
    }
    int main()
    {
        ll Mod,i,Sum=0,ans=1;
        R(Mod);
        R(n); R(m);
        for(i=1;i<=m;i++) Sum+=(Num[i]=read());
        if(Sum>n) return 0*puts("Impossible");
        for(i=1;i<=m;i++)
        {
            ans=ans*Exlucas(n,Num[i],Mod)%Mod;
            n-=Num[i];
        }
        Wl(ans);
        return 0;
    }
    /*
    input
    286572286
    843547440 1
    262584859
    output
    44088044
    
    input
    100
    4 2
    1
    2
    output
    12
    */
    View Code
  • 相关阅读:
    Oracle.EntityFrameworkCore使用时报错:Specified cast is not valid
    .net core webapi通过中间件获取请求和响应内容
    金额数字语音播报
    FluentData微型ORM
    记阿里巴巴数据采集
    给定一个N阶矩阵A,输出A的M次幂(M是非负整数)(Java)
    求出区间[a,b]中所有整数的质因数分解。(Java)(转载)
    最大公约数 最小公倍数(Java)
    十六进制转八进制(Java)
    杨辉三角形(java)
  • 原文地址:https://www.cnblogs.com/gaojunonly1/p/10560804.html
Copyright © 2011-2022 走看看