这道题应该是我的反思题。
千万自己要注意,如果一个数n没有被完全分解,答案千万要记得ans*=2因为还有一个比1e6更大的素数存在作为他的因子!!
我明明找到了a的约数个数/2-a在b一下的约数个数==答案;
但是没看到题是不能是正方形wa惨了,为什么会有这个答案?其实多找几组就可以看出来,其实就是约数是对称的。
注意这里题上说b可能为边长,所以必须是从【1,b)中的a的约数个数!!!
#include<map>
#include<list>
#include<ctime>
#include<queue>
#include<deque>
#include<cmath>
#include<stack>
#include<string>
#include<cstdlib>
#include<cstring>
#include<sstream>
#include<fstream>
#include <iostream>
#include<algorithm>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//ll gcd(ll a,ll b){
// return b?gcd(b,a%b):a;
//}
//ll QP(ll x,ll n,ll Mod){
// ll res=1;
// while(n){
// if(n&1){
// res=(res*x)%Mod;
// }
// x=(x*x)%Mod;
// n>>=1;
// }
// return res;
//}
//素数筛选
const int N = 1e6 + 10;
int pri[600010], k;//k记录素数的个数,这里的素数是从下标为0开始的
bool Isprime[N];
void prime()
{
k = 0;
memset(Isprime, true, sizeof(Isprime));
Isprime[1] = false;
for(int i = 2 ; i < N ; i++)
{
if(Isprime[i])
{
pri[k++] = i;
for(int j = 2 ; i * j < N ;j++)
Isprime[i * j] = false;
}
}
}
int main(){
prime();
ll n,a,b,g=1,cnt1,cnt2,ans1,ans;
scanf("%lld",&n);
while(n--){
scanf("%lld %lld",&a,&b);
ll t=a;
if(b*b>=a){
printf("Case %lld: %lld\n",g++,0);
continue;
}
//求a的约数和b的约数个数
ans1=1;
for(int i=0;i<k&&pri[i]*pri[i]<=a;i++){
cnt1=0;
while(a%pri[i]==0){
a/=pri[i];
cnt1++;
}
ans1*=(cnt1+1);
}
if(a>1) ans1*=2;
cnt2=0;
for(int i=1;i<b;i++){//因为题上说b可能是最小边长,而不是确定了的,所以这里需要找b一下的a的约数
if(t%i==0) cnt2++;
}
ans=ans1/2-cnt2;
printf("Case %lld: %lld\n",g++,ans);
}
return 0;
}