Sample Input
2
10 2
12 2
Sample Output
Case 1: 1
Case 2: 2
题目大意:给你两个数a和b,a是长方形的面积(这个长方形是非常单纯的长方形,他没有两条相等的边),长方形的宽大于等于b(,不管宽怎么膨胀,宽是永远小于长滴)。而我们就是要求出满足条件的长宽的对数。
解题思路:因为今天刚学的唯一分解定理,知道要用,但不知道如何用,所以就看了看dalao的题解,恍然大悟~~,唯一分解定理有以下几条应用:
目前我也只懂前两条,太菜了,显然,这题需要用到定理的第一条,那应该怎么用呢,首先我们可以利用第一条求出a的正因子个数除以2就是长宽的对数,然后求出[1,b)内a的正因子个数,两者一减,就是所求的结果了。
Code:
#include<iostream>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
using namespace std;
typedef long long ll;
const int maxn = 1e6+10;
bool p[maxn];
ll prime[maxn],cnt;
void get_prime(){//素数打表
cnt=0;
memset(prime,0,sizeof(prime));
memset(p,0,sizeof(p));
for(ll i=2;i<maxn;i++){
if(!p[i]){
prime[cnt++]=i;
for(ll j=i+i;j<maxn;j+=i){
p[j]=1;
}
}
}
}
ll cont(ll a){//求a的正因子个数
ll ans=1;
ll i=0,num=0;
while(prime[i]<a&&i<cnt){
while(a%prime[i]==0){
a/=prime[i];
num++;
}
ans*=(num+1);
num=0;
i++;
}
if(a>1) ans*=1+1;
return ans;
}
int main(){
int t,k=1;
get_prime();
scanf("%d",&t);
while(t--){
ll a,b;
ll cnt=0;
scanf("%lld %lld",&a,&b);
if(b>=sqrt(a)){//如果b大于等于a的平方根,那么长宽的乘积就会大于等于a,而长宽不能相等。
printf("Case %d: %lld
",k++,0);
continue;
}
for(ll i=1;i<b;i++){
if(a%i==0) cnt++;
}
ll temp=cont(a)/2;
// cout<<temp<<" "<<cnt<<endl;
printf("Case %d: %lld
",k++,temp-cnt);
}
return 0;
}