思路:
用Pollard_Rho做质因子分解,dfs枚举所有因子判断是否合法;
由于当\(b*b>a\)时一定无解,因此这里还可以提前判断一下;
我看其他题解的做法基本都是枚举素数做质因子分解(1E6以内素数有78498个),而\(Test\)是4e3组,这复杂度已经很高了,更离谱的是有人枚举1-b(b<1e6) ;
代码:
#include<bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
typedef __int128 LL;
typedef unsigned long long uLL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pLL;
typedef pair<double,double> pdd;
const int N=1e5+5;
const int M=4e4+5;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1.0);
const int S=100;
#define ls (i<<1)
#define rs (i<<1|1)
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define mk make_pair
#define mem(a,b) memset(a,b,sizeof(a))
LL read()
{
LL x=0,t=1;
char ch;
while((ch=getchar())<'0'||ch>'9') if(ch=='-') t=-1;
while(ch>='0'&&ch<='9'){ x=(x<<3)+(x<<1)+ch-'0'; ch=getchar(); }
return x*t;
}
std::mt19937 rnd(233);
LL factor[N];
int tot;
LL gcd(LL x,LL y)
{
return y?gcd(y,x%y):x;
}
inline LL mul(LL a,LL b,LL p)
{
return a*b%p;
}
//LL mul(LL a,LL b,LL p)
//{
// LL res=0;
// while(b)
// {
// if(b&1) res=(res+a)%p;
// a=(a+a)%p;
// b>>=1;
// }
// return res;
//}
inline LL power(LL a,LL b,LL p)
{
LL res=1;
while(b)
{
if(b&1) res=mul(res,a,p);
a=mul(a,a,p);
b>>=1;
}
return res;
}
inline bool check(LL a,LL n,LL d,LL cnt)
{
LL res=power(a,d,n);
LL las=res;
for(int i=1;i<=cnt;i++)
{
res=mul(res,res,n);
if(res==1&&las!=1&&las!=n-1) return 1;
las=res;
}
if(res!=1) return 1;
return 0;
}
bool MR(LL n)
{
if(n<2) return 0;
if(n==2) return 1;
if((n&1)==0) return 0;
LL d=n-1,cnt=0;
while((d&1)==0) d>>=1,cnt++;
for(int i=1;i<=S;i++)
{
LL a=rnd()%(n-1)+1;
if(check(a,n,d,cnt)) return 0;
}
return 1;
}
LL PR(LL n,LL k)
{
LL u=2,v=1;
LL x=rnd()%(n-1)+1;
LL y=x;
while(1)
{
x=(mul(x,x,n)+k)%n;
v++;
LL d=gcd((y-x+n)%n,n);
if(d>1&&d<=n) return d;
if(v==u)
{
y=x;
u<<=1;
}
}
}
void divide(LL n,LL k)
{
if(n==1) return ;
if(MR(n)) return (void)(factor[++tot]=n);
LL d=n,c=k;
while(d==n) d=PR(n,--c);
divide(d,c);
divide(n/d,c);
}
long long ans;
LL a,b;
LL c[N],cnt[N];
void dfs(int len,LL x)
{
//printf("%d , %lld\n",len,x);
if(len==0){
if(min(x,a/x)>=b&&x!=a/x) ans++;
return ;
}
dfs(len-1,x);
for(int i=1;i<=cnt[len];i++)
{
x*=c[len];
dfs(len-1,x);
}
}
int main()
{
int T=read();
int cas=0;
while(T--)
{
ans=tot=0;
a=read(),b=read();
divide(a,S);
sort(factor,factor+1+tot);
for(int i=1;i<=tot;i++) c[i]=factor[i];
unique(c+1,c+tot+1);
int len=0;
for(int i=1;i<=tot;i++)
{
if(factor[i]!=factor[i-1]) len++;
cnt[len]++;
}
dfs(len,1);
for(int i=1;i<=len;i++) cnt[i]=0;
printf("Case %d: %lld\n",++cas,ans>>1);
}
return 0;
}
/*
20
1000000000000 2
963761198400 5
963761198400 5
963761198400 5
963761198400 5
1000000000000 2
963761198400 5
963761198400 5
963761198400 5
963761198400 5
1000000000000 500000
963761198400 5
963761198400 5
963761198400 5
963761198400 100
*/
附一张因子个数图,前者为因子最多的数字,后者为其因子数量;(源自知乎)