链接:https://ac.nowcoder.com/acm/contest/883/D
来源:牛客网
A(n)表示一个n位1的十进制数。
给出,计算有多少
2 11 8 1 7 6 2
4 2
#include
using namespace std;
typedef long long ll;
typedef pair P;
const int MAXP = 1000000 + 5;
bool np[MAXP];
int prime[MAXP], pcnt;
void init(){
np[0] = np[1] = true;
for (register int i = 2; i < MAXP; ++i){
if (!np[i]) prime[pcnt++] = i;
for (int j = 0; j < pcnt && i * prime[j] < MAXP; ++j){
np[i * prime[j]] = true;
if (i % prime[j] == 0) break;
}
}
}
//取模数溢出int。直接乘法会炸ll
ll mul(ll a, ll b, ll p){
return (a*(b >> 25) % p*(1 << 25) + a*(b&((1 << 25) - 1))) % p;
}
ll powmod(ll a, ll b, ll p){
ll res = 1ll;
for(a%=p;b>0;b>>=1, a = mul(a,a,p)) if(b&1) res = mul(res, a, p);
return res;
}
ll p, n, m;
ll a[50];
vector pdiv;
int main(){
init();
int T; scanf("%d",&T);
while(T--){
scanf("%lld%lld%lld",&p,&n,&m);
if(p == 2ll || p == 5ll){
puts("0"); continue;
}
ll g = p*9ll; g -= g/3;
if(p != 3ll) g -= g/p;
ll tmp = g;
pdiv.clear(); //循环节g的质因子
//贪心除取最小循环节
for(int i = 0; 1ll*prime[i]*prime[i] <= tmp; i++){
if(tmp%prime[i] == 0){
while(tmp%prime[i] == 0){
if(powmod(10,g/prime[i],p*9ll) == 1ll){
tmp /= prime[i], g /= prime[i];
}else{
int cnt = 0;
while(tmp%prime[i] == 0) tmp /= prime[i], cnt++;
pdiv.push_back(P(prime[i], cnt)); //剩下的部分就是质因子次数
break;
}
}
}
}
if(tmp > 1){
if(powmod(10,g/tmp,p*9ll) == 1ll) g /= tmp;
else pdiv.push_back(P(tmp, 1));
}
//处理每个j所对应的最大的i
for(int j = 1; j <= min(40ll, m); j++){
a[j] = 1ll;
for(auto &k:pdiv)
a[j] *= powmod(k.first,(k.second+j-1)/j,g*2ll);
}
ll ans = 0;
for(int j = min(39ll, m); j >= 1; j--)
ans += 1ll*(n/a[j]);
if(m >= 40) ans += 1ll*(n/a[40])*(m-40+1);
printf("%lld\n", ans);
}
return 0;
}