## 【ZJOI2017 Round1练习&BZOJ4767】D1T3 两双手（排列组合，DP）

100%的数据：|Ax|,|Ay|,|Bx|,|By| <= 500, 0 <= n,Ex,Ey <= 500

 1 const mo=1000000007;
2 var fac,exf:array[0..1000000]of int64;
3     dp:array[1..1000]of int64;
4     x,y:array[1..1000]of longint;
5     ex,ey,sx,sy,ax,ay,bx,by:int64;
6     n,n1,i,j:longint;
7     u,v,eps:double;
8
9 function fabs(x:double):double;
10 begin
11  if x<0 then exit(-x);
12  exit(x);
13 end;
14
15 procedure swap(var x,y:longint);
16 var t:longint;
17 begin
18  t:=x; x:=y; y:=t;
19 end;
20
21 procedure qsort(l,r:longint);
22 var i,j,mid1,mid2:longint;
23 begin
24  i:=l; j:=r; mid1:=x[(l+r)>>1]; mid2:=y[(l+r)>>1];
25  repeat
26   while (mid1>x[i])or((mid1=x[i])and(mid2>y[i])) do inc(i);
27   while (mid1<x[j])or((mid1=x[j])and(mid2<y[j])) do dec(j);
28   if i<=j then
29   begin
30    swap(x[i],x[j]);
31    swap(y[i],y[j]);
32    inc(i); dec(j);
33   end;
34  until i>j;
35  if l<j then qsort(l,j);
36  if i<r then qsort(i,r);
37 end;
38
39 function c(x,y:longint):int64;
40 begin
41  exit(fac[x]*exf[y] mod mo*exf[x-y] mod mo);
42 end;
43
44 begin
45  assign(input,'hands.in'); reset(input);
46  assign(output,'hands.out'); rewrite(output);
49  fac[0]:=1; fac[1]:=1; exf[0]:=1; exf[1]:=1;
50  for i:=1 to 1000000 do fac[i]:=fac[i-1]*i mod mo;
51  for i:=2 to 1000000 do exf[i]:=exf[mo mod i]*(mo-mo div i) mod mo;
52  for i:=1 to 1000000 do exf[i]:=exf[i-1]*exf[i] mod mo;
53
54  eps:=1e-8;
55  v:=(ex*ay-ey*ax)/(bx*ay-by*ax);
56  u:=(ex*by-ey*bx)/(ax*by-ay*bx);
57  if (fabs(round(v)-v)>eps)or(fabs(round(u)-u)>eps) then
58  begin
59   writeln(0);
60   close(input);
61   close(output);
62   exit;
63  end
64   else begin inc(n); x[n]:=round(u); y[n]:=round(v); end;
65  for i:=1 to n1 do
66  begin
68   v:=(sx*ay-sy*ax)/(bx*ay-by*ax);
69   u:=(sx*by-sy*bx)/(ax*by-ay*bx);
70   if (fabs(round(v)-v)>eps)or(fabs(round(u)-u)>eps) then continue;
71   if (u<0)or(v<0) then continue;
72   if (u>x[1])or(v>y[1]) then continue;
73   inc(n); x[n]:=round(u); y[n]:=round(v);
74  end;
75  inc(n); x[n]:=0; y[n]:=0;
76  qsort(1,n);
77  dp[1]:=1;
78  for i:=2 to n do
79  begin
80   dp[i]:=c(x[i]+y[i],x[i]);
81   for j:=2 to i-1 do
82    if (x[i]>=x[j])and(y[i]>=y[j]) then
83     dp[i]:=dp[i]-dp[j]*c(x[i]+y[i]-x[j]-y[j],x[i]-x[j]) mod mo;
84   dp[i]:=(dp[i] mod mo+mo) mod mo;
85  end;
86  writeln(dp[n]);
87
88  close(input);
89  close(output);
90 end.

null

posted on 2017-02-28 15:26  myx12345  阅读(207)  评论(0编辑  收藏  举报