定义f(x)是x的各位数字之和(x十进制),定义g(x)=f(1)+f(2)+...f(x),给出a,求出一个区间l,r使得(g(r)-g(l-1) )%a==0.
首先要想办法求出g(),求解g实际上就是一个数位dp了,然后求出一个最小的x使得g(x)>=a,然后令l=1,r=x,不断调整两个区间使得g(r)-g(l-1)==a,虽然复杂度有点不科学,但实际上调整的次数不会太多....
/*=============================================================================
# Author:Erich
# FileName:
=============================================================================*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#define lson id<<1,l,m
#define rson id<<1|1,m+1,r
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll INF=1ll<<60;
const double PI=acos(-1.0);
int n,m;
ll pw[19];
ll sum[20];
ll calc(ll x)
{
if (x==0) return 0;
return 45ll*x*pw[x-1];
}
ll find(ll k)
{
ll x,y;
int num[20];
int m=0;
while(k)
{
num[m]=k%10;
m++;
k/=10;
}
ll res=0;
ll cnt=0;
for (int i=0; i<m; i++)
{
if (num[i])
{
res+=calc(i)*num[i];
res+=sum[num[i]-1]*pw[i];
res+=num[i]*(cnt+1);
}
cnt+=num[i]*pw[i];
}
return res;
}
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
pw[0]=1;
pw[1]=10;
sum[0]=0;
sum[1]=1;
for (int i=2; i<=19; i++)
pw[i]=pw[i-1]*10,sum[i]=sum[i-1]+i;
ll x,y;
ll a;
// printf("%I64d\n",find(100000000000000000LL));
// printf("%I64d\n",find(10000000000000000LL));
while(~scanf("%I64d",&a))
{
ll l=0,r=100000000000000000LL;
ll ansl,ansr;
ll mid;
while(l<r)
{
mid=(l+r)>>1;
if (find(mid)>=a) r=mid;
else l=mid+1;
}
ansl=1;
ansr=l;
x=find(ansl-1);
y=find(ansr);
while(y-x!=a)
{
if (y-x>a) ansl++;
else ansr++;
x=find(ansl-1);
y=find(ansr);
}
printf("%I64d %I64d\n",ansl,ansr);
}
return 0;
}