这个结论不明显啊…
这种题还是打表找规律吧
结论:如果当前的数是x,进行到第i次操作,若 i>x√ ,则之后的每次操作x只会加一个不变的定值 x/i
证明:
当
i>x√
时,设
x=ki
,则
i>x√,k<x√
,要使x变成(i+1)的倍数,有一个解是
(i+1)k=x+k>x
,我们要求新的值最小,但
(i+1)(k−1)=ik−i+k−1<ik−1=x−1<x
,所以
(i+1)k
已经是符合条件的最小值,于是x只会加一个定量
k=x/i
模拟到 i>x√ 就行了,显然模拟到这一步时不会改变x的数量级,复杂度 O(x√)
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
inline void read(int &x)
{
char c; while(!((c=getchar())>='0'&&c<='9'));
x=c-'0';
while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0';
}
const int maxn = 510;
ll n,m;
ll solve()
{
ll i;
for(i=1;i<=m&&(i-1)*(i-1)<=n;i++)
if(n%i) n=(n/i+1)*i;
if(i<=m)
{
--i; ll k=n/i;
n+=(m-i)*k;
}
return n;
}
int main()
{
int tcase=0;
while(scanf("%lld%lld",&n,&m)!=EOF&&n)
printf("Case #%d: %lld\n",++tcase,solve());
return 0;
}