题意:给定l,r,求区间内有多少整数,满足各位数字和能够被这个数整除 l,r<=10^18
写的数位dp的代码大数据全部WA了,但对拍找不到问题。
#include<bits/stdc++.h>
#define ull unsigned long long
using namespace std;
ull s[21][111][111][3];//p位 前缀余数是j 还有k个 lmt有没有
bool ok[21][111][111][3];
ull tar;
ull g[21];
ull u[21];
ull solve(ull p,ull j,ull k,bool lmt){
if(p==0)return k==0 and j==0;
if(p*9<k){
ok[p][j][k][lmt]=1;
s[p][j][k][lmt]=0;
return 0;
}
if(k==0){
if(j==0){
ok[p][j][k][lmt]=1;
s[p][j][k][lmt]=1;
return 1;
}
else{
ok[p][j][k][lmt]=1;
s[p][j][k][lmt]=0;
return 0;
}
}
if(ok[p][j][k][lmt])return s[p][j][k][lmt];
ok[p][j][k][lmt]=1;
s[p][j][k][lmt]=0;
for(ull i=0;i<=min(k,(lmt)?g[p]:9);i++){
s[p][j][k][lmt]+=solve(p-1,(j+i*u[p])%tar,k-i,lmt and i==g[p]);
}
return s[p][j][k][lmt];
}
ull get(ull r){//前缀
if(r==0)return 0;
ull ans=0;
ull nw=1;
while(r){
g[nw++]=r%10;
r/=10;
}
nw--;
for(ull j=1;j<=nw*9;j++){
memset(ok,0,sizeof(ok));
memset(s,0,sizeof(s));
u[1]=1;
for(ull t=2;t<=nw;t++){
u[t]=(u[t-1]*10)%j;
}
tar=j;
ans+=solve(nw,0,j,1);
}
return ans;
}
int main(){
freopen("multiple.in","r",stdin);
freopen("multiple.out","w",stdout);
ull l,r;
cin>>l>>r;
ull ans=0;
ans=get(r)-get(l-1);
cout<<ans<<endl;
return 0;
}