题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3598
数位DP...东看西看
好巧妙的思路啊!这样统计的东西就变得很简单了;
好美的 dfs!数位DP用 dfs 好像能变得很清楚。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
ll l,r,f[65][6005],ans;
int n,a[65],K;
ll dfs1(int pos,int s,bool lim)
{
if(pos==0)return s;
if(!lim&&f[pos][s]!=-1)return f[pos][s];
int end=K-1; ll ret=0;
if(lim)end=a[pos];
for(int i=0;i<=end;i++)
ret+=dfs1(pos-1,s+i*(pos-1),lim&&(i==end));
if(!lim)f[pos][s]=ret;//!lim!
return ret;
}
ll dfs(int pos,int s,int m,bool lim)
{
if(s<0)return 0;//!
if(pos==0)return s;
if(!lim&&f[pos][s]!=-1)return f[pos][s];
int end=K-1; ll ret=0;
if(lim)end=a[pos];
for(int i=0;i<=end;i++)
{
if(pos>=m)ret+=dfs(pos-1,s+i,m,lim&&(i==end));
else ret+=dfs(pos-1,s-i,m,lim&&(i==end));
}
if(!lim)f[pos][s]=ret;
return ret;
}
ll calc(ll x)
{
int n=0;
while(x)a[++n]=x%K,x/=K;
memset(f,-1,sizeof f);
ll ret=dfs1(n,0,1);
for(int i=2;i<=n;i++)
{
memset(f,-1,sizeof f);
ret-=dfs(n,0,i,1);
}
return ret;
}
int main()
{
scanf("%lld%lld%d",&l,&r,&K);
printf("%lld\n",calc(r)-calc(l-1));
return 0;
}