题目大意
给定高精度数S和T,求出T+1~S中所有满足对模3与S同余且每一位皆不为质数的数的个数。
数位DP
裸的。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
const int maxn=100000+10,mo=10007;
int pri[5];
int a[maxn],b[maxn],c[maxn],d[maxn];
int f[maxn][4][2][2];
int i,j,k,l,t,n,m,ans,x,y,z;
bool czy;
char ch;
char get(){
char ch=getchar();
while (ch!=' '&&(ch<'0'||ch>'9')) ch=getchar();
return ch;
}
int main(){
pri[1]=2;pri[2]=3;pri[3]=5;pri[4]=7;
while (1){
ch=get();
if (ch==' ') break;
a[++n]=ch-'0';
}
z=0;
fo(i,1,n){
z=z*10+a[i];
z%=3;
}
while (1){
ch=getchar();
if (ch<'0'||ch>'9') break;
b[++m]=ch-'0';
}
fd(i,n,n-m+1) b[i]=b[i-(n-m)];
fd(i,n-m,1) b[i]=0;
b[n]++;
i=n;
while (b[i]>9){
b[i]=0;
b[--i]++;
}
fd(i,n,1){
c[i]=c[i]+a[i]-b[i];
if (c[i]<0){
c[i]+=10;
c[i-1]--;
}
}
j=0;
fo(i,1,n){
j=j*10+c[i];
d[i]=j/3;
j%=3;
}
d[n]++;
i=n;
while (d[i]>9){
d[i]=0;
d[--i]++;
}
j=0;
fo(i,1,n){
j=j*10+d[i];
j%=mo;
}
ans=j;
y=0;
czy=0;
fo(i,1,n){
if (a[i]!=b[i]) break;
if (a[i]!=2&&a[i]!=3&&a[i]!=5&&a[i]!=7){
czy=1;
break;
}
y=(y+a[i])%3;
}
if (czy){
printf("%d\n",ans);
fclose(stdin);fclose(stdout);
return 0;
}
czy=0;
x=i;
if (x==1&&b[1]==0) czy=1;
fo(j,1,4){
if (pri[j]<b[x]||pri[j]>a[x]) continue;
if (pri[j]==a[x]) f[x][(y+pri[j])%3][1][0]++;
else if (pri[j]==b[x]) f[x][(y+pri[j])%3][0][1]++;
else f[x][(y+pri[j])%3][0][0]++;
}
if (czy) f[x][0][0][1]++;
fo(i,x,n-1){
if (b[i+1]!=0) czy=0;
fo(k,0,2){
if (!f[i][k][0][0]&&!f[i][k][0][1]&&!f[i][k][1][0]) continue;
fo(j,1,4){
if (pri[j]==a[i+1])
f[i+1][(k+pri[j])%3][1][0]=(f[i+1][(k+pri[j])%3][1][0]+f[i][k][1][0])%mo;
if (pri[j]==b[i+1])
f[i+1][(k+pri[j])%3][0][1]=(f[i+1][(k+pri[j])%3][0][1]+f[i][k][0][1])%mo;
f[i+1][(k+pri[j])%3][0][0]=(f[i+1][(k+pri[j])%3][0][0]+f[i][k][0][0])%mo;
if (pri[j]<a[i+1])
f[i+1][(k+pri[j])%3][0][0]=(f[i+1][(k+pri[j])%3][0][0]+f[i][k][1][0])%mo;
if (pri[j]>b[i+1])
f[i+1][(k+pri[j])%3][0][0]=(f[i+1][(k+pri[j])%3][0][0]+f[i][k][0][1])%mo;
}
}
if (czy) f[i+1][0][0][1]++;
}
ans=((ans-f[n][z][0][0]-f[n][z][0][1]-f[n][z][1][0])%mo+mo)%mo;
printf("%d\n",ans);
return 0;
}