TLE&WA 50pts?
查看原帖
TLE&WA 50pts?
390770
D2T1xubiaoshi楼主2021/12/26 23:07
//P4720
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int N = 1e6 + 10;
ll a[N], b[N]; int tot;
ll qp(ll a, ll b, ll p){
	ll ans = 1;
	while(b){ if(b&1) ans=ans*a%p; a=a*a%p; b>>=1; }
	return ans;
}
void exgcd(ll &x, ll &y, ll a, ll b){
    if(!b){ x = 1, y = 0; return; }
    exgcd(x, y, b, a%b);
    ll z = x; x = y; y = z - a / b * y;
}
ll inv(ll x, ll p){ ll a, k; exgcd(a, k, x, p); return (a % p + p) % p; }
ll calc(ll n, ll p, ll pk){
    if(!n) return 1; ll ans = 1;
    for(ll i = 1; i <= pk; ++ i) if(i%p) ans = ans * i % pk;
    ans = qp(ans, n/pk, pk);
    for(ll i = 1; i <= n%pk; ++i) if(i%p) ans = ans * i % pk;
    return ans * calc(n/p, p, pk) % pk;
}
ll C(ll n, ll m, ll p, ll pk){
    if(!n || !m || n==m) return 1; if(n < m) return 0;
    ll nn = calc(n, p, pk), mm = calc(m, p, pk), nm = calc(n-m, p, pk);
    int cnt = 0, k = n - m;//cnt即上文k1-k2-k3
    while(n) n /= p, cnt += n;
    while(m) m /= p, cnt -= m;
    while(k) k /= p, cnt -= k;
    return nn * inv(mm, pk) % pk * inv(nm, pk) % pk *
           qp(p, cnt, pk) % pk;
}
ll CRT(){
    ll M = 1, ans = 0;
    for(int i = 1; i <= tot; ++ i) M *= b[i];
    for(int i = 1; i <= tot; ++ i)
        ans += a[i] * (M/b[i]) % M * inv(M/b[i], b[i]) % M;
    return (ans % M + M) % M;
}
ll exLucas(ll n, ll m, ll p){
    for(ll i = 2; i * i <= p && p >= 1; ++ i){
        ll pk = 1;
        while(p%i == 0) p /= i, pk *= i;
        if(pk > 1) a[++tot] = C(n, m, i, pk), b[tot] = pk;
    }
    if(p > 1) a[++tot] = C(n, m, p, p), b[tot] = p;
    return CRT();
}

int main(){
	ll n, m, p;
	scanf("%lld%lld%lld", &n, &m, &p);
	printf("%lld\n", exLucas(n, m, p));
	return 0;
}

加了龟速乘也没用

2021/12/26 23:07
加载中...