• 洛谷 P2183 [国家集训队]礼物


    题目链接

    扩展卢卡斯板子

    #include<bits/stdc++.h>
    using namespace std;
    
    #define ll long long 
    
    ll gcd(ll x, ll y) { return !y ? x : gcd(y, x % y); }
    ll exgcd(ll a, ll b, ll &x, ll &y){
        if(!b) { x = 1; y = 0; return a; }
        ll ret = exgcd(b, a % b, y, x);
        y -= a/b * x; return ret;
    }
    ll ksm(ll x,ll y,ll mod){
        ll z = 1;
        while(y){
            if(y & 1) z = z * x % mod;
            y >>= 1; x = x * x % mod;
        }
        return z;
    }
    ll inv(ll a,ll mod){
        ll x,y; exgcd(a,mod,x,y);
        return (x % mod + mod) % mod;
    }
    
    ll f(ll n,ll p,ll p_k){
        if(n == 0) return 1;
        ll ret1 = 1, ret2 = 1;
        for(ll i = 1; i <= p_k; ++ i) if(i % p) ret1 = ret1 * i % p_k;
        ret1 = ksm(ret1, n/p_k, p_k);
        for(ll i = p_k * (n/p_k); i <= n; ++ i) if(i % p) ret2 = ret2 * (i % p_k) % p_k;
        return f(n/p, p, p_k) * ret1 % p_k * ret2 % p_k;
    }
    ll g(ll n, ll p){
        if(n < p) return 0;
        return g(n/p,p) + (n/p);
    }
    ll lucas(ll n, ll m, ll p, ll k, ll p_k){
        return f(n,p,p_k) * inv(f(m,p,p_k),p_k) % p_k * inv(f(n - m, p,p_k),p_k) % p_k * ksm(p, g(n,p) - g(m,p) - g(n - m,p), p_k) % p_k;    
    }
    ll exlucas(ll n, ll m, ll mod){
        ll x = mod; ll ret = 0; 
        ll A,M;
        for(ll i = 2; i * i <= x; ++ i){
            if(x % i) continue;
            
            ll tim = 0; M = 1;
            while(x % i == 0) ++ tim, x /= i, M *= i;
            A = lucas(n,m,i,tim,M);
            ret = (ret + A * (mod / M) % mod * inv(mod / M, M) % mod) % mod;
        }
        if(x > 1){
            ll A = lucas(n,m,x,1,x);
            ret = (ret + A * (mod / x) % mod * inv(mod / x, x) % mod) % mod;
        }
        return ret;
    }
    
    int P,n,m;
    int main(){
        ll ans = 1;
        scanf("%d%d%d",&P,&n,&m);
        for(int i = 1; i <= m; ++ i){
            int x; scanf("%d",&x);
            if(x > n) { puts("Impossible"); return 0; }
            ans = (ans * exlucas(n,x,P) % P);
            n -= x;
        }
        printf("%lld
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    C# Thread Lambda
    C#中Invoke的用法
    C#抽象类和抽象方法
    SQL Server2005杂谈(2):公用表表达式(CTE)的递归调用
    改变自己的128种方法
    小技巧
    Linux学习第一章作业.zxs
    Linux学习第二、三章作业.zxs
    Linux 系统管理 04—账号管理
    Mysql中的in和find_in_set的区别?
  • 原文地址:https://www.cnblogs.com/zzhzzh123/p/13438332.html
Copyright © 2020-2023  润新知