题目
Input
Sample Input
4 2
5 35 15 45
40 20 10 30
Output
Sample Output
8
Data Constraint
题解
我们可以先分别把a,b都排一下序,然后设p[i]表示比a[i]小的b数组中的数的个数,在排序之后这个东西显然可以线性时间求出
然后我们设f[i,j]表示当前已经做完了前i个人,现在对于A队的i个人每个人有两种情况
1:这个人已经选择了击败B队里的一个人
2:这个人没有选择对手
由于A中的人的能力值是单调上升的,那么显然有
f[i,j]=f[i−1,j−1]+f[i−1,j]∗(p[i]−j+1)
然后我们设g[i]表示A队中至少有i个人获胜的情况数,那么根据定义,有
g[i]=f[n,i]∗(n−i)!,因为有n-i个人还没有选择对手嘛,而且我们随便给他们找个对手都是可以的
最后我们可以设h[i]表示A队中有i个人获胜的方案数,那么有
h[i]=g[i]−∑j=i+1nh[j]∗Cij
其中使用组合数的原因是对于每一个从有j个人赢到有i个人赢的方案都可以产生贡献
然后需要注意的是n,k同奇偶时才有解,然后k=0时注意不要重复统计答案了
贴代码
const
md=1000000007;
var
f:array[-1..2005,-1..2005]of int64;
g,h,a,b,p,cc:array[0..2005]of int64;
i,j,k,l,m,n:longint;
procedure qsort(l,r:longint);
var
i,j,mid:longint;
begin
i:=l;
j:=r;
mid:=a[(i+j) div 2];
repeat
while a[i]<mid do inc(i);
while a[j]>mid do dec(j);
if i<=j then
begin
a[0]:=a[i];
a[i]:=a[j];
a[j]:=a[0];
inc(i);
dec(j);
end;
until i>j;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end;
procedure qsort1(l,r:longint);
var
i,j,mid:longint;
begin
i:=l;
j:=r;
mid:=b[(i+j) div 2];
repeat
while b[i]<mid do inc(i);
while b[j]>mid do dec(j);
if i<=j then
begin
b[0]:=b[i];
b[i]:=b[j];
b[j]:=b[0];
inc(i);
dec(j);
end;
until i>j;
if l<j then qsort1(l,j);
if i<r then qsort1(i,r);
end;
function quickmi(x,y:int64):int64;
var
a,b,p:int64;
begin
x:=x mod md;
a:=1;
b:=x;
while y>0 do
begin
if y mod 2=1 then a:=(a*b) mod md;
y:=y div 2;
b:=(b*b) mod md;
end;
exit(a);
end;
begin
//assign(input,'t3.in'); reset(input);
readln(n,k);
if (n mod 2)<>(k mod 2) then
begin
writeln(0);
halt;
end;
for i:=1 to n do read(a[i]);
readln;
for i:=1 to n do read(b[i]);
readln;
qsort(1,n);
qsort1(1,n);
b[n+1]:=maxlongint;
for i:=1 to n do
begin
p[i]:=p[i-1];
while a[i]>b[p[i]+1] do inc(p[i]);
end;
f[0,0]:=1;
for i:=1 to n do
for j:=0 to i do f[i,j]:=(f[i-1,j]+f[i-1,j-1]*(p[i]-j+1)) mod md;
cc[0]:=1;
cc[1]:=1;
for i:=2 to n do cc[i]:=(cc[i-1]*i) mod md;
for i:=0 to n do g[i]:=(f[n,i]*cc[n-i]) mod md;
for i:=n downto 0 do
begin
h[i]:=g[i];
for j:=i+1 to n do h[i]:=(md+h[i]-
(h[j]*
((quickmi(cc[i]*cc[j-i],md-2)*cc[j]) mod md)) mod md) mod md;
end;
if k=0 then writeln(h[n div 2]) else
writeln((h[(k+n) div 2]+h[(n-k) div 2]) mod md);
//close(input);
end.