思路:
问题转化为
1
0
k
∗
x
+
d
d
d
d
d
…
…
(
k
个
)
≡
b
y
(
m
o
d
10^k*x+ddddd……(k个)≡by(mod
10k∗x+ddddd……(k个)≡by(mod
b
)
b)
b)
->
1
0
k
∗
x
−
b
y
≡
d
d
d
d
d
…
…
(
m
o
d
10^k*x-by≡ddddd……(mod
10k∗x−by≡ddddd……(mod
b
)
b)
b)
直接枚举k,然后用exgcd求出x的最小正整数解,然后看在不在范围内
c o d e code code
#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
const ll MAXN = 1e4 + 10;
ll a[MAXN];
ll P, d, len;
ll exgcd(ll a, ll b, ll &x, ll &y) {
if(b == 0) {
x = 1;
y = 0;
return a;
}
ll r = exgcd(b, a % b, y, x);
y -= a / b * x;
return r;
}
bool check(ll A, ll C, ll l) {
if(l == len) {
if(C % P) return 0;
if(d == 0) return 0;
for(ll i = len - 1; i >= 0; i --)
if(a[i] > d) return 1;
else if(a[i] < d) return 0;
return 1;
}
ll limit = 0, flag = 0;
if(len - l >= 8) limit = P;
else {
for(ll i = len - 1; i >= l; i --)
limit = limit * 10 + a[i];
for(ll i = l - 1; i >= 0; i --)
if(a[i] < d) { flag = 1; break; }
else if(a[i] > d) break;
if(flag) limit --;
limit = min(limit, P);
}
if(limit < 1 && d == 0) return 0;
ll x = -1, y = -1;
ll gcd = exgcd(A, P, x, y);
ll dx = P / gcd;
if(C % gcd) return 0;
x = (x * (C / gcd) % dx + dx) % dx;
if(x == 0) {
if(d != 0) return limit >= 0;
else return dx <= limit;
}
else return x <= limit;
}
int main() {
cin>>P>>d;
string s;
cin>>s;
len = s.size();
for(ll i = 0; i < len; i ++)
a[i] = s[len - i - 1] - '0';
ll tmp = 0, ten = 1, ans = 0;
for(ll i = 1; i <= len; i ++) {
tmp = (tmp * 10 + d) % P;
ten = ten * 10 % P;
if(check(ten, (P - tmp) % P, i))
ans = i;
}
printf("%lld\n", ans);
return 0;
}