exLucas 求调,急,玄关
查看原帖
exLucas 求调,急,玄关
685183
LightSpot楼主2024/8/22 11:36

代码如下(很丑):

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 4e7 + 10;
int T;
map <int, bool> not_pri;
int qpow(int n , int m , int mod = 0)
{
	int res = 1;
	while(m)
	{
		if(m & 1)
		{
			res *= n;
			if(mod) res %= mod;
		}
		n *= n;
		if(mod) n %= mod;
		m >>= 1;
	}
	return res;
}
long long count_x(int n , int p , int k)
{
    if(!n) return 1;
    long long ans = 0 , rp = qpow(p , k);
    ans = count_x(n / p , p , k) % rp;
    long long tmp = 1;
    if(n / rp)
	{
		for(int i = 2 ; i <= rp ; i++) if(i % p) tmp *= i , tmp %= rp;
		ans *= qpow(tmp , n / rp , rp) % rp;
	}
    tmp = 1;
    for(int i = n / rp * rp + 1 ; i <= n ; i++) if(i % p) tmp *= i , tmp %= rp;
    ans *= tmp , ans %= rp;
    return ans;
}
void exgcd(long long a , long long b , long long &x , long long &y)
{
	if(b == 0)
	{
		x = 1 , y = 0;
		return;
	}
	exgcd(b , a % b , y , x);
	y -= a / b * x;
}
int cntp(int n , int p)
{
	long long k = p , ans = 0;
    while(n / k)
	{
        ans += n / k;
        k *= p;
    }
    return ans;
}
long long f(int n , int m , int a , int b)
{
	long long p = qpow(a , b);
	int v1 = count_x(n , a , b) , v2 = count_x(m , a , b) * count_x((n - m) , a , b);
	long long inv = 0 , tmp = 0;
	exgcd(v2 , p , inv , tmp);
	while(inv < 0) inv += p;
	v1 *= inv;
	long long x = cntp(n , a) - cntp(m , a) - cntp(n - m , a);
	if(x && b == 1) return 0;
	x = qpow(a , x);
	x *= v1 , x %= p;
	return x;
}
long long C(int n , int m , int mod)
{
	long long ans = 0;
	int tmod = mod;
    for(int i = 2 ; tmod > 1 ; i += ((i & 1) ? 2 : 1))
	{
		if(!(tmod % i))
		{
			int k = qpow(2 , (int)log2((int)(log10(tmod) / log10(i)) + 1) + 1) , tans = 0;
        	long long p = qpow(i , k);
        	while(k)
			{
    	        if(!(tmod % p))
				{
    	        	tmod /= p;
    	            tans += k;
        	    }
   	 	        k /= 2;
   	    	    p = qpow(i, k);
        	}
        	long long tval = f(n , m , i , tans);
			int np = qpow(i , tans);
       		long long m = mod / np , inv  = 0 , tmp = 0;
        	exgcd(m , np , inv , tmp);
        	while(inv < 0) inv += np;
//        	cout << m << ' ' << np << ' ' << inv << ' ' << tmp << endl;
        	ans = (ans + tval * m * inv) % mod;
		}
    }
    return ans % mod;
}
signed main()
{
    cin >> T;
    while(T--)
	{
        int n , m , Q;
        scanf("%lld%lld%lld" , &n , &m , &Q);
        printf("%lld\n" , C(n + m, n, Q));
    }
    return 0;
}

不要直接把自己AC代码贴上的那种

2024/8/22 11:36
加载中...