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];
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 void cal()
26 {
27     for(int i = 0; i < cnt && p[i] <= sqrt(tmp); i++)
28     {
29         int cc = 0;
30         while(tmp % p[i] == 0)
31         {
32             cc ++;
33             tmp /= p[i];
34         }
35         num *= (cc + 1);
36  
37     }
38     if(tmp > 1) //如果tmp不能被整分,说明还有一个素数是它的约数,此时cc=1
39         num *= 2;
40 }
41  
42 int main()
43 {
44     int T;
45     scanf("%d", &T);
46     cnt = 0;
47     get_prime();
48     for(int ca = 1; ca <= T; ca++)
49     {
50         scanf("%lld %lld", &a, &b);
51         if(a < b * b)
52             printf("Case %d: 0\n", ca);
53         else
54         {
55             num = 1;
56             tmp = a;
57             cal();
58             num /= 2;
59             for(int i = 1; i < b; i++)
60                 if(a % i == 0)
61                     num --;
62             printf("Case %d: %d\n", ca, num);
63         }
64     }
65 }
View Code

猜你喜欢

转载自www.cnblogs.com/LJHAHA/p/10380896.html
今日推荐