Pairs Forming LCM LightOJ - 1236

原题链接

考察:质数筛+唯一分解定理

这道题的思路与该题GO 的解法二相同

错误思路:

       预处理质数,分解质因数,dfs两个约数,结果是TLE 时间是2891ms

正确思路:

      如同上题的解法二.本蒟蒻一开始的思路也是这个,但是本蒟蒻没想出来lcm(8,3)这种情况怎么统计= = ,只想到一方为n,另一方的种类数是约数个数的情况

      这道题的思路不应该是a,b数一个一个考虑.而是将质因数一个个考虑.

对于约数a,b.它们质因数的指数的最大值决定了lcm的值.假设 n = p1a1p2a2p3a3...pkak 我们不是需要a、b某一方完全与n相等,而是需要a或b的质因数p某一方能够提供piai这样n才能有pa的质因数.对于每一位i,都有ai+1种选择,而a b谁提供又是两种选择.除去指数完全相等的情况,每个质因数总共是(ai+1)*2-1选择.因此累乘即可

最后在计算答案时需要/2去掉a b 与b a的情况,但这样 a a的情况被多去了,因此再+1

每个质因数选择都要*2,不乘2就是我一开始的思路一方确定是n,另一方任意的情况= = 

 

坑点:

        本题的质数不能只筛到1e7,这样大质数分解不了因数

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 typedef long long ll;
 5 typedef pair<ll,int> pll;
 6 const int N = 1e7+50;//1e14需要大于1e7的素数才能筛掉它
 7 int prime[N/10],cnt,ans;
 8 bool st[N];
 9 void GetPrime(int n)
10 {
11     for(int i=2;i<=n;i++)
12     {
13         if(!st[i]) prime[++cnt] = i;
14         for(int j=1;prime[j]<=n/i;j++)
15         {
16             st[i*prime[j]] = 1;
17             if(i%prime[j]==0) break;
18         }
19     }
20 }
21 ll GetDivide(ll n)
22 {
23     ll res = 1;
24     for(int i=1;prime[i]<=n/prime[i];i++)
25     {
26         if(n%prime[i]==0)
27         {
28             int p = prime[i],s = 0;
29             while(n%p==0) n/=p,s++;
30             res *=(s+1)*2-1;
31         }
32     }
33     if(n>1) res*=2*2-1;
34     return res;
35 }
36 int main()
37 {
38     int T,kcase = 0;
39     GetPrime(1e7+30);
40     scanf("%d",&T);
41     while(T--)
42     {
43         ll n;  scanf("%lld",&n);
44         ll tmp = GetDivide(n);
45         printf("Case %d: %lld\n",++kcase,tmp/2+1);
46     }
47     return 0;
48 }

 

posted @ 2021-01-26 17:59  acmloser  阅读(45)  评论(0编辑  收藏  举报