Aladdin and the Flying Carpet LightOJ - 1341
考察:质数筛+约数+dfs
思路:
预处理1e6以内的质数,用质数分解a,枚举小于√a的约数,加上一点剪枝(注意:矩形不包括正方形)
讲一下几个坑点:
- 判定res是否超过√a时,不要用res*res判断,会溢出,y总真是yyds
- 提醒我自己,线性筛模板真的不要再写错了!!!!外层循环是到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 }