Aladdin and the Flying Carpet LightOJ - 1341(合数)唯一分解定理

题目链接

题目大意:有一个数a,求有多少组(n1,n2)n1*n2=a 且n1>=b&&n2>=b;

(n1,n2) (n2,n1)算一种;

思路:直接求[b,√a)有多少满足条件的数肯定是不行的。

唯一分解定理:

对于一个大于1正整数n可以分解质因数
 
则n的正约数的个数就是
  
其中a1、a2、a3…ak是p1、p2、p3,…pk的指数。

因为a不可能出现(x,x)这组数,所以也f(n)/ 2  即为 答案

又因为pi都为素数,所以可以打一个素数表来优化时间


代码:

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
long long  a,b;
const int maxn=1000047;
long long  cnt=1;
int prim[maxn],p[maxn];  
int k = 0;  
void find_prim()  
{
    k = 0;  
    for(int  i = 2; i < maxn; i++)  
    {  
        if(!p[i])  
        {  
            prim[k++] = i;  
            for(int  j = i+i; j < maxn; j+=i)  
            {  
                p[j] = 1;  
            }  
        }  
    }  
} 
void get(){
	cnt=1;
	int j=0;
	for(int i=0;prim[i]<=a/prim[i];i++){ //prim[i]<a&&i<k用这个的话耗时比较大
		if(a%prim[i]==0){
			j=0;
			while(a%prim[i]==0){
				a/=prim[i];
				j++;
			}
			cnt*=(j+1);
		} 
	}
	if(a>1) cnt*=2;
	cnt/=2;
}
int main()
{
	find_prim();
	
	int t;
	scanf("%d",&t);
	for(int k=1;k<=t;k++){
		scanf("%lld%lld",&a,&b);
		long long c=a;
		if(b*b>=a) {
			cnt=0;
		}
		else {
			get();
			for(int i=1;i<b;i++){
				if(c%i==0) cnt--;
			}
		}
		printf("Case %d: %lld\n",k,cnt);
	} 
	return 0;
 } 



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章