Aladdin and the Flying Carpet LightOJ - 1341

原题链接

考察:质数筛+约数+dfs

思路:

      预处理1e6以内的质数,用质数分解a,枚举小于√a的约数,加上一点剪枝(注意:矩形不包括正方形)

讲一下几个坑点:

  1. 判定res是否超过√a时,不要用res*res判断,会溢出,y总真是yyds
  2. 提醒我自己,线性筛模板真的不要再写错了!!!!外层循环是到n!!!!
 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <vector>
 5 using namespace std;
 6 typedef long long ll;
 7 typedef pair<int,int> pii; 
 8 const int N = 1e6+10;
 9 int cnt,prime[N],ans;
10 bool st[N];
11 ll a,b; 
12 vector<pii> v;
13 void GetPrime(ll n)
14 {
15     for(int i=2;i<=n;i++)
16     {
17         if(!st[i]) prime[++cnt] = i;
18         for(int j=1;prime[j]<=n/i;j++)
19         {
20             st[i*prime[j]] = 1;
21             if(i%prime[j]==0) break;
22         }
23     }
24 }
25 void GetDivide(ll n)
26 {
27     for(int i=1;prime[i]<=n/prime[i];i++)
28     {
29         if(n%prime[i]==0)
30         {
31             int s = 0;
32             while(n%prime[i]==0) s++,n/=prime[i];
33             v.push_back({prime[i],s});
34         }
35     }
36     if(n>1) v.push_back({n,1});
37 }
38 ll qsm(int n,int k)
39 {
40     ll res = 1;
41     while(k)
42     {
43         if(k&1) res = res*n;
44         k>>=1;
45         n = (ll)n*n;
46     }
47     return res;
48 }
49 void dfs(int k,ll res)
50 {
51     if(res>=a/res) return;
52     if(k==v.size())
53     {
54         if(res>=b) ans++;//,printf("%d\n",res)
55         return;
56     }
57     for(int i=0;i<=v[k].second;i++)
58     {
59         ll tmp = qsm(v[k].first,i);
60         if(tmp>a||tmp*tmp>a||tmp*res>a) break;
61         dfs(k+1,res*tmp);
62     }
63 }
64 int main()
65 {
66     GetPrime(1e6+5);
67     int T,kcase = 0;
68     scanf("%d",&T);
69     while(T--)
70     {
71         v.clear(); ans = 0;
72         scanf("%lld%lld",&a,&b);
73         GetDivide(a);
74         dfs(0,1);
75         printf("Case %d: %d\n",++kcase,ans);
76     }
77     return 0;
78 } 

 

posted @ 2021-01-25 22:09  acmloser  阅读(47)  评论(0编辑  收藏  举报