ATcoder2038 【桁和 / Digit Sum】

本文探讨了一种特殊数学问题的高效求解策略,通过分析不同情况下的算法表现,提出了一种结合枚举与质因数分解的O(sqrt(n))复杂度算法,有效解决了在1≤n≤10^11范围内找到满足特定条件的b值的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 先考虑一些特殊情况比如n>sn > sn>sn=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}1n1011,朴素做法肯定会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 = nab+t=na+t=sa+t=sa+t=s
  • 那么我们有(b−1)∗a=n−s(b-1)*a=n-s(b1)a=ns
  • 那么答案就在n−sn-sns的质因数中了。
  • 枚举质因数,这道题就变成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;
}

又是一道结论题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值