今天补题,昨天是我太猖狂了,在机房吹牛,然后说着说着忘了时间,后来楼长来了,我们走了,CF没打成。
不扯了,下面说题;
题目的意思是给你n和k,
n代表最后得出的号码有n为,然后k能被n整除,就是把n这串号码分成k分,然后每份有n/k个数位。
在下面一行有n/k个数ai,第三行为n/k个数bi;
然后不是有n/k个数位么,这里面对应填的就是 是ai的整数倍,位数不超过k位且这个数开头不能以bi开头。
问一共有多少种不同的号码能组成。
那么先求每个数位上符合要求的有多少个,共k个数位,每个数位上的个数记为c[i],那么最后的结果就是k个c[i]相乘对1e9+7取余。
每个空格上的符合要求的元素是ai的倍数且首位不能是bi,如果bi!=0要求的每格元素要是n/k位,所以如果是ai的倍数且不足n/k位的首位是不是就是0了,就都符合要求,
因为要n/k位那么最大能取到的数就是t=1e(n/k)-1,那t/ai+1,就是在1到t间ai的倍数的个数,那么要减不合要求的就是bi*(1e(n/k)-1)-1到(bi+1)*(1e(n/k)-1)-1之间能整除ai数的个数,
因为在这区间里都是以bi开头。
如果bi为0,那么不合要求的是不是就是那些以0开头的,就是在k=1e(n/k-1)-1,k/ai+1,就是不合要求的个数。
最后每格合要求的个数就是t-不合要求的。
1 /*sjy*/ 2 #include<stdio.h> 3 #include<algorithm> 4 #include<iostream> 5 #include<string.h> 6 #include<stdlib.h> 7 const long long N=1e9+7; 8 typedef long long ll; 9 using namespace std; 10 ll a[100005]; 11 ll b[100005]; 12 int main(void) 13 { 14 ll i,j,k,p,q,s,pp; 15 while(scanf("%I64d %I64d",&p,&q)!=EOF) 16 { 17 k=p/q; 18 pp=1; 19 for(i=0; i<k; i++) 20 scanf("%I64d",&a[i]); 21 for(i=0; i<k; i++) 22 scanf("%I64d",&b[i]); 23 for(i=0; i<k; i++) 24 { 25 ll sum=0; 26 ll cn=1; 27 for(j=0; j<q-1; j++) 28 { 29 cn*=10; 30 } 31 if(b[i]!=0) 32 { 33 ll x1=cn*(b[i]+1)-1;//(bi+1)*(1e(n/k)-1)-1 34 ll x2=cn*b[i]-1;//bi*(1e(n/k)-1)-1 35 sum=x1/a[i]-x2/a[i]; 36 sum=(cn*10-1)/a[i]+1-sum;//(t=cn*10-1) 37 } 38 else if(b[i]==0) 39 { 40 sum+=(cn-1)/a[i];//首位为零的个数 41 sum=(cn*10-1)/a[i]-sum; 42 } 43 44 pp=(pp%N*sum%N)%N; 45 } 46 printf("%I64d ",pp); 47 } 48 return 0; 49 }