您的位置:首页 > 其它

【Codeforces Round 330 (Div 2)B】【数值统计 端点思维】Pasha and Phone 电话号码 每块数是x倍数却不能以y开头方案数

2015-12-03 12:57 633 查看
B. Pasha and Phone

time limit per test
1 second

memory limit per test
256 megabytes

input
standard input

output
standard output

Pasha has recently bought a new phone jPager and started
adding his friends' phone numbers there. Each phone number consists of exactly n digits.
Also Pasha has a number k and
two sequences of length n / k (n is
divisible by k) a1, a2, ..., an / k and b1, b2, ..., bn / k.
Let's split the phone number into blocks of length k. The first block will be formed by digits
from the phone number that are on positions 1, 2,..., k,
the second block will be formed by digits from the phone number that are on positions k + 1, k + 2,
..., 2·k and so on. Pasha considers a phone number good,
if the i-th block doesn't start from the digit bi and
is divisible by ai if
represented as an integer.
To represent the block of length k as
an integer, let's write it out as a sequence c1, c2,...,ck.
Then the integer is calculated as the result of the expression c1·10k - 1 + c2·10k - 2 + ... + ck.
Pasha asks you to calculate the number of good phone
numbers of length n, for the given k, ai and bi.
As this number can be too big, print it modulo 109 + 7.

Input
The first line of the input contains two integers n and k (1 ≤ n ≤ 100 000, 1 ≤ k ≤ min(n, 9)) —
the length of all phone numbers and the length of each block, respectively. It is guaranteed that n is
divisible by k.
The second line of the input contains n / k space-separated
positive integers — sequence a1, a2, ..., an / k (1 ≤ ai < 10k).
The third line of the input contains n / k space-separated
positive integers — sequence b1, b2, ..., bn / k (0 ≤ bi ≤ 9).

Output
Print a single integer — the number of good phone numbers of length n modulo 109 + 7.

Sample test(s)

input
6 2
38 56 49
7 3 4


output
8


input
8 2
1 22 3 44
5 4 3 2


output
32400


Note
In the first test sample good phone numbers are: 000000, 000098, 005600, 005698, 380000, 380098, 385600, 385698.

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1,class T2>inline void gmax(T1 &a,T2 b){if(b>a)a=b;}
template <class T1,class T2>inline void gmin(T1 &a,T2 b){if(b<a)a=b;}
const int N=1e5+10,M=0,Z=1e9+7,ms63=1061109567;
int n,k;
int a
,b
;
int TOP;
int cnt(int x,int y)
{
int tot=TOP/x+1;

int bot=(TOP+1)/10*y;
int top=(TOP+1)/10*(y+1)-1;
int first=bot/x;if(bot%x)++first;
int last=top/x;

return tot-(last-first+1);
}
int main()
{
while(~scanf("%d%d",&n,&k))
{
TOP=1;for(int i=1;i<=k;++i)TOP*=10;--TOP;
LL ans=1;
for(int i=n/k;i;--i)scanf("%d",&a[i]);
for(int i=n/k;i;--i)scanf("%d",&b[i]);
for(int i=i=n/k;i;--i)ans=ans*cnt(a[i],b[i])%Z;
printf("%lld\n",ans);
}
return 0;
}
/*
【题意】
比较难懂。我们来理解一波——
有n个数字,每个数字是几是不确定的。
我们把它们划分为n/k份,每份的数字个数为k。
对于第i块,所有数字,顺序构成一个数,要求这个数必须是a[i]的倍数,且不能以b[i]为开头。
让你输出,这n个数字的可能方案数是多少

【类型】
数值统计 端点思维

【分析】
显然,每一块的方案数相对独立,我们算出每一块的方案数,乘起来,便是答案。
而对于一块内,要如何计算?
我们知道,一块内的数,是从0到TOP的,TOP==10^k-1
首先,要求这个数是a[i]的倍数,0肯定满足,除此之外,数的可能个数是TOP/a[i]
然后,要求这个数不能以b[i]为开头,以b[i]开头的数的范围是(b[i]0000 b[i]9999)
我们求出first number和last number,总数里剔除(last-first+1)个数,便得到了答案!

【时间复杂度&&优化】
O(n)

【数据】
input
27 9
100000000 100000000 100000000
0 0 0
output
729

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  题库-CF CodeForces