• luogu1445 [violet]樱花 阶乘分解


    题目大意

    求方程$$frac{1}{x}+frac{1}{y}=frac{1}{N!}$$的正整数解的组数。

    思路

    咱们把式子整理得$$xy-(x+y)N!=0$$。$xy$和$x+y$?貌似可以因式分解?!于是$$N!^2 - (x + y)N! + xy = N!^2$$,即$$(x-N!)(y-N!)=N!^2$$。令$A=x-N!,B=y-N!$,则原式变为$$A*B=(N!)^2$$。因此,解的个数便是$N!^2$的因子的个数。根据唯一分解定理,任意的正整数都可分解为$prod p_i^{c_i}$,根据阶乘分解的方法,每个$c_i = sum_{i=1}^{log_p N}frac{N}{p^i}$。对于$N!^2$,其质因数分解出的每一个$c_i$都是$N!$质因数分解出的$c_i$的2倍。根据因数个数定理,一个数的因数的个数=$prod c_i+1$。

    综上所述,应当对$N!$进行阶乘分解,再将求出的$2c_i+1$,将对于每一个$p_i$的上式结果相乘即为所求。

    注意

    本题数字大,因此一切数量值类型都要用long long。

    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    const int MAX_N = 1000010, MAX_P_CNT = 5000, P = 1e9 + 7;
    
    int GetPrime(int *prime, int n)
    {
    	static bool NotPrime[MAX_N];
    	memset(NotPrime, false, sizeof(NotPrime));
    	int primeCnt = 0;
    	for (int i = 2; i <= n; i++)
    	{
    		if (!NotPrime[i])
    			prime[primeCnt++] = i;
    		for (int j = 0; j < primeCnt; j++)
    		{
    			if (i*prime[j] > n)
    				break;
    			NotPrime[i*prime[j]] = true;
    			if (i%prime[j] == 0)
    				break;
    		}
    	}
    	return primeCnt;
    }
    
    int Proceed(int n, int *prime)
    {
    	long long ans = 1;
    	for (int i = 0; prime[i] <= n; i++)
    	{
    		long long k = 0;
    		for (long long j = prime[i]; j <= n; j *= prime[i])
    			k += (long long)n / j;
    		ans = (ans * (k * 2 + 1)) % P;
    	}
    	return ans;
    }
    
    int main()
    {
    	int n;
    	static int prime[MAX_N];
    	scanf("%d", &n);
    	GetPrime(prime, MAX_N - 1);
    	printf("%d
    ", Proceed(n, prime));
    	return 0;
    }
    

      

  • 相关阅读:
    吉他 摄影
    前端思考独处时间自我成长
    约束力
    js算法
    旅行计划
    生产者消费者问题
    Lock锁
    线程和进程
    什么是JUC
    GC日志分析和垃圾回收器的新展望
  • 原文地址:https://www.cnblogs.com/headboy2002/p/8849633.html
Copyright © 2020-2023  润新知