Never gonna tell a lie and hurt you
RedLycoris · · 题解
题目翻译是错误的,正确的如下:
给定两个正整数
题解:
这个
显然无法分块,考虑怎么做到根号分治。我们先对
-
K \ge T
当
-
K \le T
我们可以考虑把
均衡一下取
Code:
#include<bits/stdc++.h>
#define ll long long
#define int ll
using namespace std;
ll k,m,n;
int ee[13];
ll dp[13][10000][91][2];
inline void add(ll&x,ll y){x+=y;}
signed main(){
cin>>k>>m;
ll ans=0;ll tm=m;
for(int i=1;;++i){
ee[i]=tm%10;
tm/=10;
if(tm==0){
n=i;
break;
}
}
reverse(ee+1,ee+n+1);
if(k>=10000){
for(int i=0;i<=90;++i){
for(ll ee=i;ee<=m;ee+=k){
ll t=ee,cnt=0;
while(t){
cnt+=t%10;
t/=10;
}
if(cnt%k==i)++ans;
}
}
cout<<ans-1<<'\n';
return 0;
}
dp[1][0][0][0]=1;
for(int i=1;i<=n;++i){
for(int j=0;j<k;++j){
for(int sm=0;sm<=90;++sm){
{//f=0
for(int t=0;t<ee[i];++t){
if(sm+t<=90){
add(dp[i+1][(j*10+t)%k][sm+t][1],dp[i][j][sm][0]);
}
}
if(sm+ee[i]<=90)add(dp[i+1][(j*10+ee[i])%k][sm+ee[i]][0],dp[i][j][sm][0]);
}
{//f=1
for(int t=0;t<10;++t)if(sm+t<=90)add(dp[i+1][(j*10+t)%k][sm+t][1],dp[i][j][sm][1]);
}
}
}
}
for(int ee=0;ee<=90;++ee)add(ans,dp[n+1][ee%k][ee][0]),add(ans,dp[n+1][ee%k][ee][1]);
cout<<ans-1<<'\n';
}