Aladdin and the Flying Carpet(唯一分解定理)
Posted ljhaha
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Aladdin and the Flying Carpet(唯一分解定理)相关的知识,希望对你有一定的参考价值。
题目大意:给两个数a,b,求满足c*d==a且c>=b且d>=b的c,d二元组对数,(c,d)和(d,c)属于同一种情况;
首先了解唯一分解定理:
题目思路:根据唯一分解定理有:
1.每个数n都能被分解为:n=p1^a1*p2^a2*^p3^a3……pn^an(p为素数);
2.n的正因数的个数sum为:sum=(1+a1)*(1+a2)*(1+a3)……(1+an);
最短边为m,若m>=sqrt(n),则无解。所以m最多我10^6,可遍历找出1-m中n的因子,并用sum去减去这类因子的个数。
代码解析:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5 #define ll long long 6 using namespace std; 7 int const MAX = 1e6 + 10; 8 int p[MAX];//用于存素数 9 bool u[MAX];//u[i]标记数字i是否为素数 10 int num, cnt; 11 ll a, b, tmp; 12 13 void get_prime() 14 { 15 memset(u, false, sizeof(u)); 16 for(int i = 2; i <= sqrt(MAX); i++) 17 if(!u[i]) 18 for(int j = i * i; j <= MAX; j += i) 19 u[j] = true; 20 for(int i = 2; i <= MAX; i++) 21 if(!u[i]) 22 p[cnt ++] = i; 23 } 24 25 //唯一分解定理的正体 26 void cal() 27 { 28 for(int i = 0; i < cnt && p[i] <= sqrt(tmp); i++) 29 { 30 int cc = 0; 31 while(tmp % p[i] == 0) 32 { 33 cc ++; 34 tmp /= p[i]; 35 } 36 num *= (cc + 1); 37 38 } 39 if(tmp > 1) //如果tmp不能被整分,说明还有一个素数是它的约数,此时cc=1 40 num *= 2; 41 } 42 43 int main() 44 { 45 int T; 46 scanf("%d", &T); 47 cnt = 0; 48 get_prime(); 49 for(int ca = 1; ca <= T; ca++) 50 { 51 scanf("%lld %lld", &a, &b); 52 if(a < b * b) 53 printf("Case %d: 0 ", ca); 54 else 55 { 56 num = 1; 57 tmp = a; 58 cal(); 59 num /= 2; 60 for(int i = 1; i < b; i++) 61 if(a % i == 0) 62 num --; 63 printf("Case %d: %d ", ca, num); 64 } 65 } 66 }
以上是关于Aladdin and the Flying Carpet(唯一分解定理)的主要内容,如果未能解决你的问题,请参考以下文章
C - Aladdin and the Flying Carpet
LightOJ 1341 - Aladdin and the Flying Carpet 基本因子分解
[LightOJ 1341] Aladdin and the Flying Carpet (算数基本定理(唯一分解定理))
Aladdin and the Flying Carpet(唯一分解定理)