题意:
话说有一个问题是如果b很大的话去掉小于b的因子应该会超时才对= = 不知道是不是数据水...
给出整数 a 和 b ,求区间[b, a] 内的 a 的约数对的个数
解法:
一个整数n可以表示为若干素数乘积: n = p1^a1 * p2^a2*…*pm^am;
则 n 的正因数的个数可以表示为: num = (a1+1)*(a2+1)…(am+1);
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstdlib>
using namespace std;
typedef long long ll;
const int maxn = 1e6+5;
ll prime[maxn];
bool is_prime[maxn];
int k ; //素数个数
void get_prime(int n)//打素数表
{
k = 0;
memset(is_prime,true,sizeof(is_prime));
is_prime[0] = is_prime[1] = false;
for(int i=2;i<=n;i++)
{
if(is_prime[i])
{
prime[k++] = i;
for(int j=2*i;j<=n;j+=i)
is_prime[j] = false;
}
}
}
ll get_factor(ll m)//唯一分解定理求正因子个数
{
ll ans = 1;
for(ll i=0;prime[i]*prime[i]<=m&&i<k;i++)
{
ll cnt = 0;
if(m%prime[i]==0)
{
while(m%prime[i]==0)
{
cnt++;
m = m/prime[i];
}
ans = ans * (cnt+1);
}
}
if(m>1)
ans = ans*2;
return ans;
}
int main()
{
get_prime(maxn);
int T,cas;
cin>>T;
for(int cas=1;cas<=T;cas++)
{
ll a,b;
scanf("%lld%lld",&a,&b);
if(b*b>=a)
printf("Case %d: %lld\n",cas,0);
else
{
ll ans = get_factor(a);
ans = ans>>1;
for(ll i=1;i<b;i++) //将小于b的因子去掉
if(a%i==0)
ans--;
printf("Case %d: %lld\n",cas,ans);
}
}
return 0;
}
话说有一个问题是如果b很大的话去掉小于b的因子应该会超时才对= = 不知道是不是数据水...