- 先考虑一些特殊情况比如n>sn > sn>s与n=sn=sn=s时
- 当n>sn > sn>s时,可以想象这样是无解的
- 当n=sn = sn=s时,b=n+1b = n + 1b=n+1
- 然后呢,先考虑朴素做法:枚举nnn以内所有数,作为bbb。
- 当然1≤n≤10111\leq n \leq 10^{11}1≤n≤1011,朴素做法肯定会TLE。
- 当然看这个范围,如果以O(n)O(\sqrt n)O(n)的算法肯定可过。
- 我们就想想以n\sqrt nn为分界线
- 小于n\sqrt nn就可以直接枚举bbb的值
- 而大于n\sqrt nn时又会怎么样呢
- 可设整数a,ta, ta,t使得a∗b+t=na * b + t = na∗b+t=n与a+t=sa+t=sa+t=s
- 那么我们有(b−1)∗a=n−s(b-1)*a=n-s(b−1)∗a=n−s
- 那么答案就在n−sn-sn−s的质因数中了。
- 枚举质因数,这道题就变成O(n)O(\sqrt n)O(n)了。
code:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n, s, ans = -1;
inline ll read() {
ll s = 0, f = 1;
char ch;
for(; ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) s = (s << 1) + (s << 3) + ch - '0';
return s * f;
}
inline ll f(ll b, ll n) {
ll ans = 0;
while(n) ans += n % b, n /= b;
return ans;
}
int main() {
n = read(), s = read();
ll u = sqrt(n) + 1;
for(ll i = 2; i <= u; ++i) if(f(i, n) == s) { ans = i; break; }
if(n == s) { ans = n + 1; }
if(ans == -1 && n > s) {
ll c = n - s;
u = c / (u - 1) + 1;
for(ll i = u; i >= 1; --i) {
ll b = c / i + 1;
if(!(c % i) && s >= i && (s - i) < b && i < b) {
ans = b;
break;
}
}
}
printf("%lld\n", ans);
return 0;
}
又是一道结论题