回到题目,由于 a 与 x 并不互质,我们需要约分。具体地,在输入之后将 a 中 2 和 5 的质因数全部除掉。将处理后的 a 写作 a',这时,x 满足条件当且仅当 x = b \times {2}^{p} \times {5}^{q} 且 x \in [l, r],其中 b 为 a' 的因数,p、q 为非负整数。
证明非常简单:分子上 a' 把 b 消掉了,此时 \frac{a'}{b} 与 {2}^{p} \times {5}^{q} 互质,因此原式为有限小数。
因此我们枚举 a' 的因数 b,然后枚举 p、q,得到合法的 x。由于质因数分解是唯一的,这样枚举可以做到不重不漏。这里有一个常用的枚举因数的技巧:只枚举 \le \sqrt {a'} 的 b,另一个因数即为 \frac{a'}{b}。但是需要判断 b = \sqrt {a'} 的情况。
记得开 long long。
复杂度分析
时间复杂度
枚举 b 为 O(\sqrt {a'}),枚举 p、q 为 O(\log_{2} r \times \log_{5} r),后者由于 r \le {10}^{15} 大约为 1000,总复杂度为 O(\sqrt {a'} \times \log_{2} r \times \log_{5} r),可以通过。
空间复杂度
只需定义若干单独变量,复杂度 O(1)。
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
int a,l,r,ans;
signed main()
{
cin>>a>>l>>r;
while(a%2==0) a/=2;
while(a%5==0) a/=5;
for(int b=1;b*b<=a;b++)
if(a%b==0)
{
for(int i=b;i<=r;i*=2)
for(int j=i;j<=r;j*=5)
if(l<=j) ans++;
if(b*b!=a)
for(int i=a/b;i<=r;i*=2)
for(int j=i;j<=r;j*=5)
if(l<=j) ans++;
}
cout<<ans;
}