[COCI 2013/2014 ROUND 3] parovi
分析:简单的数位统计
f[i][j]表示第i位为j的方案数,显然f数组是满足区间减法的,即[1,B]的f的值减去[1,A-1]的f的值便是[A,B]的f数组的值,我们的得到了f数组后就很好解决了:
只需枚举位数i和数对的第i位,j和k:ans+=abs(j-k)*f[i][j]*f[i][k]
下面便是代码
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #define maxlen 50010 6 #define Mod 1000000007 7 #define LL long long 8 using namespace std; 9 10 char A[maxlen],B[maxlen]; 11 int lenr,lenl,len,L[maxlen],R[maxlen]; 12 LL f[maxlen][10],g[maxlen],ten[maxlen],ans; 13 14 void Calc() 15 { 16 ten[0]=1; 17 for (int i=1;i<=maxlen;i++) ten[i]=(ten[i-1]*10)%Mod; 18 LL r=0; 19 lenr=strlen(B+1); 20 for (int i=1;i<=lenr;i++) R[i]=B[lenr-i+1]-'0'; 21 g[lenr+1]=0; 22 for (int i=lenr;i;i--) g[i]=(g[i+1]*10+R[i])%Mod; 23 for (int i=1;i<=lenr;i++) 24 { 25 for (int j=0;j<=9;j++) 26 { 27 f[i][j]=(g[i+1]*ten[i-1])%Mod; 28 if (j<R[i]) f[i][j]=(f[i][j]+ten[i-1])%Mod; 29 else if (j==R[i]) f[i][j]=(f[i][j]+r+1)%Mod; 30 } 31 r=(r+R[i]*ten[i-1])%Mod; 32 } 33 lenl=strlen(A+1); 34 for (int i=1;i<=lenl;i++) L[i]=A[lenl-i+1]-'0'; 35 L[1]--; 36 for (int i=1;i<=lenl;i++) if (L[i]<0){L[i]+=10;L[i+1]--;} 37 while (lenl>1 && !L[lenl]) lenl--; 38 lenl=lenr; 39 memset(g,0,sizeof g); 40 for (int i=lenl;i;i--) g[i]=(g[i+1]*10+L[i])%Mod; 41 r=0; 42 for (int i=1;i<=lenl;i++) 43 { 44 for (int j=0;j<=9;j++) 45 { 46 f[i][j]=(f[i][j]-g[i+1]*ten[i-1]+Mod)%Mod; 47 if (j<L[i]) f[i][j]=(f[i][j]-ten[i-1]+Mod)%Mod; 48 else if (j==L[i]) f[i][j]=(f[i][j]-r-1+Mod)%Mod; 49 } 50 r=(r+L[i]*ten[i-1])%Mod; 51 } 52 len=max(lenr,lenl); 53 ans=0; 54 for (int i=1;i<=len;i++) 55 for (int j=0;j<=9;j++) 56 for (int k=0;k<=9;k++) ans=(ans+f[i][j]*f[i][k]*abs(j-k))%Mod; 57 } 58 59 int main() 60 { 61 scanf("%s%s",A+1,B+1); 62 Calc(); 63 cout<<ans<<endl; 64 return 0; 65 }