LightOJ1236 (分解质因数)

题意: 给定 n n ,求出 l c m ( i , j ) = n lcm(i,j)=n 的数对个数。其中 1 i j n 1\leq i\leq j\leq n
数据范围: 1 n 1 0 14 1\leq n \leq 10^{14}

题解: 对于一个数 x x ,分解质因数后得到: x = p 1 α 1 p 2 α 2 . . . p k α k x=p_1^{\alpha_1}p_2^{\alpha_2}...p_{k}^{\alpha_k}
那么对于 l c m ( A , B ) = p 1 m a x ( a 1 , b 1 ) p 2 m a x ( a 2 , b 2 ) . . . p k m a x ( a k , b k ) lcm(A,B)=p_1^{max(a_1,b_1)}p_2^{max(a_2,b_2)}...p_k^{max(a_k,b_k)}

  • 对于 n n 以内的数, a i , b i [ 0 , α i ] a_i,b_i\in[0,\alpha_i] ,所以对于 a i , b i a_i,b_i 都有 α i + 1 \alpha_i+1 种选择,不过注意当两者同取最大幂时,该幂只能被取一次,所以共 2 α i + 1 2\alpha_i+1 次。
  • 其次,由于 A B A\leq B ,而由于最大幂只能取一次,所以 A = n , B = n A=n,B=n 只出现一次,其余均出现了 2 2 次。故最后答案是 ( i = 1 k 2 α i + 1 ) 2 + 1 \lfloor\frac{(\prod_{i=1}^k 2\alpha_i+1)}{2}\rfloor+1
#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int N = 1e7 + 10;
int pri[N / 10], cnt;
bool st[N];

void xs(int n) {
	st[0] = st[1] = true;
	for(int i = 2; i <= n; ++i) {
		if(!st[i]) pri[++cnt] = i;
		for(int j = 1; j <= cnt && 1ll * i * pri[j] <= n; ++j) {
			st[i * pri[j]] = true;
			if(i % pri[j] == 0) break;
		}
	}
}

int gcd(int a, int b) {
	return b == 0 ? a : gcd(b, a % b);
} 

int lcm(int a, int b) {
	return a / gcd(a, b) * b;
}

long long pairsFormLCM( int n ) {
    long long res = 0;
    for( int i = 1; i <= n; i++ )
        for( int j = i; j <= n; j++ )
           if( lcm(i, j) == n ) printf("#(%d, %d\n)", i, j), res++; // lcm means least common multiple
    return res;
}

int main()
{
	xs(N - 1);
	int T; scanf("%d", &T);
	for(int k = 1; k <= T; ++k) {
		ll n; scanf("%lld", &n);
		
		ll res = 1;
		for(int j = 1; j <= cnt && 1ll * pri[j] * pri[j] <= n; ++j) {
			if(n % pri[j] == 0) {
				int temp = 0;
				while(n % pri[j] == 0) n /= pri[j], ++temp;
				res *= (2 * temp + 1);
			}
		}
		if(n > 1) res *= (2 * 1 + 1);
		res = res / 2 + 1;
		printf("Case %d: %lld\n", k, res);
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_43900869/article/details/107603276