zoukankan      html  css  js  c++  java
  • bzoj2142: 礼物

    拓展Lucas板子放一手

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> pa;
    
    int mod;
    int plen,p[30],mip[30];
    void emmmm()
    {
        int k=mod;
        for(int i=2;i*i<=mod;i++)
            if(k%i==0)
            {
                p[++plen]=i,mip[plen]=1;
                while(k%i==0)k/=i,mip[plen]*=i;
            }
        if(k!=1)p[++plen]=k,mip[plen]=k;
    }
    //~~~~~~~~~~~~~~~~~~~分解mod~~~~~~~~~~~~~~~~~~~~~ 
    void exgcd(int a,int b,int &x,int &y)
    {
        if(a==0)
        {
            x=0,y=1;
            return ;
        }
        else
        {
            int tx,ty;
            exgcd(b%a,a,tx,ty);
            x=ty-b/a*tx;
            y=tx;
        }
    }
    LL inv(int A,int B)//不是质数不能用快速幂求逆元!! 
    {
        int x,y;
        exgcd(A,B,x,y);
        return (x%B+B)%B;
    }
    //~~~~~~~~~~~~~~~getinv(mod p)~~~~~~~~~~~~~~~~~~~~~~~~
    LL quick_pow(int A,int p,int mo) 
    {
        int ret=1;
        while(p!=0)
        {
            if(p%2==1)ret=(LL)ret*A%mo;
            A=(LL)A*A%mo;p/=2;
        }
        return ret;
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    
    //-----------------------------------------init-----------------------------------------------------------------
    
    pa solve(int n,int id)//first p[id]因子个数,second n!除了这些因子的值 
    {
        if(n==0)return make_pair(0,1);
        
        LL ans=1;
        int d=n/mip[id];
        if(d>0)
        {
            for(int i=2;i<mip[id];i++)
                if(i%p[id]!=0)ans=ans*i%mip[id];
            ans=quick_pow(ans,d,mip[id]);
        }
        for(int i=d*mip[id]+1;i<=n;i++)
            if(i%p[id]!=0)ans=ans*i%mip[id];
            
        pa t=solve(n/p[id],id);
        return make_pair(n/p[id]+t.first,ans*t.second%mip[id]);
    }
    LL calc(int n,int m,int id)
    {
        if(n<m)return 0;
        pa a=solve(n,id),b=solve(m,id),c=solve(n-m,id);
        LL t1=quick_pow(p[id],a.first-b.first-c.first,mip[id])*a.second%mip[id];
        LL t2=inv(b.second,mip[id])%mip[id];
        LL t3=inv(c.second,mip[id])%mip[id];
        return t1*t2*t3%mip[id];
    }
    LL aa[30];
    LL crt()
    {
        int M=mod,ret=0;
        for(int i=1;i<=plen;i++)
            ret=(ret+aa[i]*(M/mip[i])%mod*inv(M/mip[i],mip[i])%mod)%mod;
        return ret;
    }
    LL exlucas(int n,int m)
    {
        for(int i=1;i<=plen;i++)aa[i]=calc(n,m,i);
        return crt();
    }
    
    //-------------------------------------getC-----------------------------------------------
    
    int w[30];
    int main()
    {
        int n,m,s=0,x;
        scanf("%d%d%d",&mod,&n,&m);emmmm();
        for(int i=1;i<=m;i++)
            scanf("%d",&w[i]), s+=w[i];
        if(s>n){printf("Impossible
    ");return 0;}
        
        LL ans=exlucas(n,s);
        for(int i=1;i<=m;i++)
            ans=ans*exlucas(s,w[i])%mod, s-=w[i];
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    使用HTTP协下载文件
    DNS协议 实践
    操作系统学习笔记 线程
    操作系统学习笔记 进程
    操作系统学习笔记 操作系统概述
    操作系统学习笔记 栈
    操作系统学习笔记 概述
    C语言中的fread和fwrite
    【原】python-jenkins信息
    【转】通过python调用jenkins 常用api操作
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9911261.html
Copyright © 2011-2022 走看看