有了bzoj1430的经验解决这题就不是什么难事了
首先考虑度数确定的点,令tot=sigma(d[i]-1)
首先给这tot个数分配prufer编码的位置有C(tot,n-2)种方案
每个方案中是可以进行可重复排列的,对应tot!/[(d[1]-1)!*(d[2]-1)!*…*(d[k]-1)!] 这里都是已确定的度数的点
下面考虑无所谓的点,这些可以在prufer序列中随意分配
因此答案是m^(n-2-tot) (m表示未确定度数的点的个数)
根据乘法原理答案就是C(tot,n-2)*m^(n-2-tot)*tot!/[(d[1]-1)!*(d[2]-1)!*…*(d[k]-1)!]
=(n-2)!*m^(n-2-tot)/[(d[1]-1)!*(d[2]-1)!*…*(d[k]-1)!*(n-2-tot)!]
肯定要高精度,但是我们要尽量避免除法
考虑到这里计算出的方案一定是整数,于是我们可以先质因数分解,然后消去,这要就是单精度的高精度乘法了

 1 var d:array[0..1010,0..1010] of longint;
 2     a,p,c:array[0..1010] of longint;
 3     ans:array[0..100010] of longint;
 4     l,i,m,x,n,w,j,t:longint;
 5     f:boolean;
 6 
 7 procedure mul(x,y:longint);
 8   var i,j,u,v:longint;
 9   begin
10     for i:=1 to y do
11     begin
12       v:=0;
13       for j:=1 to l do
14       begin
15         u:=ans[j]*x+v;
16         v:=u div 10;
17         ans[j]:=u mod 10;
18       end;
19       while v>0 do
20       begin
21         inc(l);
22         ans[l]:=v mod 10;
23         v:=v div 10;
24       end;
25     end;
26   end;
27 
28 begin
29   readln(n);
30   for i:=2 to n do
31   begin
32     f:=true;
33     for j:=2 to trunc(sqrt(i)) do
34       if i mod j=0 then
35       begin
36         f:=false;
37         break;
38       end;
39     if f then
40     begin
41       inc(t);
42       p[t]:=i;
43     end;
44   end;
45   for i:=1 to n do
46   begin
47     readln(a[i]);
48     if a[i]<>-1 then m:=m+a[i]-1
49     else inc(w);
50   end;
51   for i:=2 to n-2 do
52   begin
53     for j:=1 to t do
54       d[i,j]:=d[i-1,j];
55     x:=i;
56     j:=1;
57     while x<>1 do //预处理阶乘的质因数分解
58     begin
59       while (x<>1) and (x mod p[j]=0) do
60       begin
61         x:=x div p[j];
62         inc(d[i,j]);
63       end;
64       inc(j);
65     end;
66   end;
67   ans[1]:=1;
68   l:=1;
69   x:=w;
70   j:=1;
71   while x<>1 do  //m^(n-2-tot)的质因数分解
72   begin
73     while (x<>1) and (x mod p[j]=0) do
74     begin
75       x:=x div p[j];
76       c[j]:=c[j]+(n-2-m);
77     end;
78     inc(j);
79   end;
80 
81   for i:=1 to t do
82     c[i]:=c[i]+d[n-2,i]-d[n-2-m,i];
83 
84   for i:=1 to n do
85     if a[i]<>-1 then
86     begin
87       for j:=1 to t do
88         c[j]:=c[j]-d[a[i]-1,j];
89     end;
90   for i:=1 to t do
91     mul(p[i],c[i]);
92   for i:=l downto 1 do
93     write(ans[i]);
94   writeln;
95 end.
96 
97  
View Code

 

posted on 2014-12-25 19:29  acphile  阅读(123)  评论(0编辑  收藏  举报