Title Description
Give you two numbers m and d
Give you two numbers L , r
Interrogation interval [l, r] are satisfied even bit number is the number of d and d is not odd bit number (bits from the left) is a multiple of m
1 <=m <= 2000 , 0 <= d <=9
l <= r <= 10 ^ 2000
To ensure that a <= b and a and b are the same number of bits
answer
A start has been considered the leading zero, discuss thief trouble, look after the problem solution found did not consider leading zeros, a look at the English title only to find the same number of digits. There can not be a bit odd d do not know. (Or learn good English)
Then it is simple, direct f [s] [sum] s-enumeration current position, the current number mod m = sum
Read a character, so l directly special sentenced to facilitate that, but if l-1, then the number of bits less likely to go wrong.
#include<bits/stdc++.h> using namespace std; const int mod=1000000007; const int maxn=2005; int m,d; int len,num[maxn]; int f[maxn][maxn]; char l[maxn],r[maxn]; int dfs(int s,int sum,int lim){ if(!s) return !sum; if(!lim&&f[s][sum]!=-1) return f[s][sum]; int mx= lim ? num[s] : 9 ; int ret=0; for(int i=0;i<=mx;i++){ if((len-s)&1) {if(i!=d) continue;} else if(i==d) continue; ret=(ret+dfs(s-1,(sum*10+i)%m,lim&&i==mx))%mod; } if(!lim) f[s][sum]=ret; return ret; } bool check(){ int x=0; for(int i=len;i;i--){ if((len-i)&1){if(num[i]!=d) return false;} else if(num[i]==d) return false; x=(x*10+num[i])%m; } return !x; } int cx(){ memset(f,-1,sizeof(f)); len=strlen(r+1); for(int i=1;i<=len;i++) num[i]=r[len-i+1]-'0'; int temp2=dfs(len,0,true); len=strlen(l+1); for(int i=1;i<=len;i++) num[i]=l[len-i+1]-'0'; int temp1=dfs(len,0,true); int ans=temp2-temp1; ans+=check(); return ans; } int main(){ scanf("%d%d",&m,&d); scanf("%s%s",l+1,r+1); printf("%d",(cx()%mod+mod)%mod); }
If the number is not the same, then it should open two dimensions: whether the current position is odd, whether with leading zeros.
Consider only whether the record is a bit odd transfer is correct, if the memory of the first words of the current position and the sum must be the same, so as
00xxxx...
0000xx...
If there is a first-fill method, just follow the second filling enough.
This question is okay, because d is not filled to the first bit so I do not need to consider d = 0. So if direct bit is even filled d; otherwise it is an enumeration, can not take d, if there is no leading zeros or is this a Motian 0 then the parity-digit next bit will change, otherwise unchanged.
#include<bits/stdc++.h> using namespace std; const int mod=1000000007; const int maxn=2005; int m,d; int len,num[maxn]; int f[maxn][maxn][2][2]; char l[maxn],r[maxn]; int dfs(int s,int sum,int lim,bool even,bool qdl){ if(!s) return !sum&&!qdl; if(!lim&&f[s][sum][even][qdl]!=-1) return f[s][sum][even][qdl]; int mx= lim ? num[s] : 9 ; int ret=0; if(!even){ if(lim&&mx<d) return 0; ret=dfs(s-1,(sum*10+d)%m,lim&&d==mx,!even,false); if(!lim) f[s][sum][even][qdl]=ret; return ret; } for(int i=0;i<=mx;i++){ if(i==d) continue; if(qdl&&!i) ret=(ret+dfs(s-1,sum*10%m,lim&&i==mx,even,true))%mod; else ret=(ret+dfs(s-1,(sum*10+i)%m,lim&&i==mx,!even,false))%mod; } if(!lim) f[s][sum][even][qdl]=ret; return ret; } bool check(){ int x=0; for(int i=len;i;i--){ if((len-i)&1){if(num[i]!=d) return false;} else if(num[i]==d) return false; x=(x*10+num[i])%m; } return !x; } int cx(){ memset(f,-1,sizeof(f)); len=strlen(r+1); for(int i=1;i<=len;i++) num[i]=r[len-i+1]-'0'; int temp2=dfs(len,0,true,true,true); len=strlen(l+1); for(int i=1;i<=len;i++) num[i]=l[len-i+1]-'0'; int temp1=dfs(len,0,true,true,true); int ans=temp2-temp1; ans+=check(); return ans; } int main(){ scanf("%d%d",&m,&d); scanf("%s%s",l+1,r+1); printf("%d",(cx()%mod+mod)%mod); }
0 There Laid full sentence, or when l = 1 0 if legitimate, when d = 0, from 0 rdfs not legitimate.
Write code r- (l-1), but does not know why he hung up, because it seems to get more answers from l-1.
#include<bits/stdc++.h> using namespace std; const int mod=1000000007; const int maxn=2005; int m,d; int len,num[maxn]; int f[maxn][maxn][2][2]; char l[maxn],r[maxn]; int dfs(int s,int sum,int lim,bool even,bool qdl){ if(!s) return !sum&&!qdl; if(!lim&&f[s][sum][even][qdl]!=-1) return f[s][sum][even][qdl]; int mx= lim ? num[s] : 9 ; int ret=0; if(!even){ if(lim&&mx<d) return 0; ret=dfs(s-1,(sum*10+d)%m,lim&&d==mx,!even,false); if(!lim) f[s][sum][even][qdl]=ret; return ret; } for(int i=0;i<=mx;i++){ if(i==d) continue; if(qdl&&!i) ret=(ret+dfs(s-1,sum*10%m,lim&&i==mx,even,true))%mod; else ret=(ret+dfs(s-1,(sum*10+i)%m,lim&&i==mx,!even,false))%mod; } if(!lim) f[s][sum][even][qdl]=ret; return ret; } int cx(){ memset(f,-1,sizeof(f)); len=strlen(r+1); for(int i=1;i<=len;i++) num[i]=r[len-i+1]-'0'; int temp2=dfs(len,0,true,true,true); memset(f,-1,sizeof(f)); len=strlen(l+1); for(int i=1;i<=len;i++) num[i]=l[len-i+1]-'0'; num[1]--; for(int i=1;i<=len;i++){ if(num[i]>=0)break; num[i]+=10; num[i+1]--; } if(!num[len]) len--; int temp1=dfs(len,0,true,true,true); int ans=temp2-temp1; return ans; } int main(){ scanf("%d%d",&m,&d); scanf("%s%s",l+1,r+1); printf("%d",(cx()%mod+mod)%mod); }
Does anyone know help me (orz)