# bzoj3598: [Scoi2014]方伯伯的商场之旅【数位dp】

#### Description

1 * 2 + 2 * 1 + 3 * 0 + 1 * 1 + 2 * 2 = 9

3 8 3

5

#### HINT

1 < = L < = R < = 10^15, 2 < = K < = 20

#### 解题思路：

#include<bits/stdc++.h>
#define ll long long
using namespace std;

int k,num[60];
ll l,r,len,f[60][1200][2];

ll dfs1(int pos,int sum,bool lim)
{
if(pos>len)return sum;
if(f[pos][sum][lim]!=-1)return f[pos][sum][lim];
ll res=0;int end=(lim?num[pos]:k-1);
for(int i=0;i<=end;i++)
res+=dfs1(pos+1,sum+i*(pos-1),lim&&(i==end));
return f[pos][sum][lim]=res;
}

ll dfs2(int pos,int sum,int m,bool lim)
{
if(pos>len)return max(sum,0);
if(f[pos][sum][lim]!=-1)return f[pos][sum][lim];
ll res=0;int end=(lim?num[pos]:k-1);
for(int i=0;i<=end;i++)
res+=dfs2(pos+1,sum+(pos<m?-i:i),m,lim&&(i==end));
return f[pos][sum][lim]=res;
}

ll solve(ll n)
{
len=0;
while(n)num[++len]=n%k,n/=k;
reverse(num+1,num+len+1);
memset(f,-1,sizeof(f));
ll res=dfs1(1,0,1);
for(int i=2;i<=len;i++)
{
memset(f,-1,sizeof(f));
res-=dfs2(1,0,i,1);
}
return res;
}

int main()
{
//freopen("lx.in","r",stdin);
scanf("%lld%lld%d",&l,&r,&k);
cout<<solve(r)-solve(l-1);
return 0;
}