[算數基本定理] LightOJ 1341
阿新 • • 發佈:2019-02-18
題目大意
給出面積n,和最短邊m,求能形成的矩形的個數(不能為正方形)。
題目思路
根據算數基本定理有:
1.每個數n都能被分解為:n=p1^a1*p2^a2*^p3^a3……pn^an(p為素數);2.n的正因數的個數sum為:sum=(1+a1)(1+a2)(1+a3)……(1+an);
最短邊為m,若m>=sqrt(n),則無解。所以m最多我10^6,可遍歷找出1-m中n的因子,並用sum去減去這類因子的個數。
#include<cstdio>
#include<stdio.h>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#define INF 0x3f3f3f3f
#define MAX 1000005
#define mod 1000000007
using namespace std;
long long p[MAX],v[MAX], num_prime;
// save prime numbers in p
void GetPrime(){
memset ( p, 0, sizeof(p));
memset( v, 0, sizeof(v));
for( int i = 2; i < MAX; ++i){
if (!v[i]){
p[++num_prime] = i;
for( int j = i; j < MAX; j += i)
v[j] = 1;
}
}
}
// all possible factors: (k1+1)*(k2+1)....
long long Ans ( long long n ){
long long cnt, sum = 1;
for( int i = 1; i <= num_prime && p[i] <= n;++i){
// p[i] is a factor of n
if ( n%p[i] == 0){
cnt = 0;
while ( n%p[i] == 0 )
{
++cnt;
n /= p[i];
}
// total number of factors
sum *= (cnt+1);
}
}
if ( n > 1 )
sum *= 2;
return sum;
}
int main(){
GetPrime();
int T;
scanf("%d",&T);
for( int k = 1; k <= T; ++k){
long long n, m;
scanf( "%lld%lld",&n,&m );
if ( n/m < m )
{
printf("Case %d: %lld\n",k,0);
continue;
}
long long ans = Ans(n) / 2;
// delete the factors less than m
for( int i = 1; i < m; ++i ){
if ( n % i == 0 )
ans--;
}
printf("Case %d: %lld\n",k,ans);
}
return 0;
}