数论专题第三题 :C - Aladdin and the Flying Carpet
Posted 1898
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数论专题第三题 :C - Aladdin and the Flying Carpet相关的知识,希望对你有一定的参考价值。
可能还是太菜了,最近每写一道题都会显得十分吃力,不过令人欣慰的是还可以从中学到不少的东西。
题目的大概意思:给出面积啊a,还有最短的边b,求出能够组成矩形一共有多少个组合。
samole input:
10 2
12 2
sample output:
1 (10一共有两对因数,2,5还有1,10);
2
分析:题目的意思很明显就是要求出a的符合条件的因数的对数找出来,那么涉及到数的因数,就应该想到“算术基本定理”,而算法基本定理又要有素数作为铺垫,所以筛选素数又要用到”欧拉函数筛选法“;
思路:先用“算术基本定理”算出a总体一共有多少个因数,在除以2来求对数,之后暴力求出1到b有多少限制的对数,两者相减便是答案。
注意事项:由于a给出的范围是10的12次方,所以素数筛选只需要筛选到10的6次方就可以了(m*m=a,过了m之后便会重复)。
第二个注意的地方也是题目最为关键的地方之一:代码如下:
if(a/b < b) //意思就是当b的限制达到a的算术平方根的时候,那么将不会在存在任何一个满足题目的组合,那么就可以直接输出结果,并且continue循环执行下一个; { printf("Case %d: %lld\n",i,0); continue; }
总体的代码走一走:
#include<cstdio> #include<iostream> #include<cstring> #define Max 1000005 #include<cmath> using namespace std; typedef long long int ll; bool vis[Max]; int p[Max],p_num=0; void ola() { memset(vis,false,sizeof(vis)); memset(p,0,sizeof(p)); for(int i=2;i<Max;i++) { if(!vis[i]) p[p_num++]=i; for(int j=0;j<p_num;j++) { if(i*p[j]>Max) break; vis[i*p[j]]=true; if(i%p[j]==0) break; } } } ll Ans(ll n) { ll sum =1; for(int i=0;i<p_num && p[i]<=n;i++) { if(n%p[i]==0) { int cnt=0; while(n%p[i]==0) { n=n/p[i]; cnt++; } sum=sum*(cnt+1); } } if(n>1) sum=sum*2; return sum; } int main() { ola(); int T; ll a,b; scanf("%d",&T); for(int i=1;i<=T;i++) { scanf("%lld %lld",&a,&b); if(a/b < b) { printf("Case %d: %lld\n",i,0); continue; } ll cnt = Ans(a)/2; for(int j=1;j<b;j++) { if(a%j==0) { cnt--; } } printf("Case %d: %lld\n",i,cnt); } return 0; }
以上是关于数论专题第三题 :C - Aladdin and the Flying Carpet的主要内容,如果未能解决你的问题,请参考以下文章
C - Aladdin and the Flying Carpet
C - Aladdin and the Flying Carpet (质因子分解,因子个数)