codeforce 595B-Pasha and Phone(数学)

今天补题,昨天是我太猖狂了,在机房吹牛,然后说着说着忘了时间,后来楼长来了,我们走了,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 }
油!油!you@
原文地址:https://www.cnblogs.com/zzuli2sjy/p/4952144.html