背景描述:
终于解出了dm同学的难题,dm同学同意帮v神联络。可dm同学有个习惯,就是联络同学的时候喜欢分组联络,而且分组的方式也很特别,要求第i组的的人数必须大于他指定的个数ci。在dm同学联络的时候,v神在想,按照dm同学的规则一共可以有多少种方案呢?他想啊想,终于……没想出来。于是他又想到了聪明的你,你能帮v神算出按照dm同学的规则有多少种分组方案吗?
题目描述:
v神的班级共有n个人,dm同学想把同学分成M组联络,要求第i组的人数必须大于给定的正整数Ci,求有多少不同的方案?(两个是相同的方案当且仅当对于任意的一队i,两个方案的第i组同学数量相等)由于结果很大,所以你只需要输出模1000000007的值。
输入格式:
第一行两个整数N和M ,后面有M行,每行一个整数,表示Ci
输出格式:
仅有一行,一个整数,方案数模1000000007的值。
样例输入:
10 3
1
2
3
样例输出:
3
样例解释:
方案有三种,每堆的个数分别是(3,3,4),(2,4,4),(2,3,5)。
数据范围约定:
对于30%的数据,N ,M<= 10
对于60%的数据,N ,M<=1000
对于100%的数据,N ,M<= 1000000 Ci<=1000
数据保证至少有一个方案
const md=800000;
md2=1000000007;
type arr=array[0..800000] of longint;
var n,m,i,j,k:longint;
sum:int64;
su,a,b:arr;
v:array[0..2000000] of boolean;
procedure sushu;
var i,j:longint;
begin
for i:=2 to md do
if not v[i] then
begin
j:=i;
repeat
inc(j,i); v[j]:=true;
until j>md;
end;
for i:=2 to md do
if not v[i] then
begin
inc(su[0]); su[su[0]]:=i;
end;
end;
procedure fenjie(x:longint; var d:arr);
var i,j:longint;
now:int64; //fuck
begin
for i:=1 to su[0] do
if su[i]>x then exit
else
begin
now:=su[i];
while (now<=md) do
begin
inc(d[i],x div now); now:=now*su[i];
end;
end;
end;
procedure main;
var i,j:longint;
begin
dec(n); dec(m);
fenjie(n,a); fenjie(n-m,b); fenjie(m,b);
for i:=1 to su[0] do
a[i]:=a[i]-b[i];
sum:=1;
for i:=1 to su[0] do
for j:=1 to a[i] do
sum:=(sum*su[i]) mod md2;
end;
begin
assign(input,'input.in'); assign(output,'output.out');
reset(input); rewrite(output);
readln(n,m);
sushu;
for i:=1 to m do
begin
readln(j); dec(n,j);
end;
main;
writeln(sum);
close(input); close(output);
end.