好题,首先有一个结论,有向无环图的树形图数目=根节点意外入度之积
现在相当于在原图上加一条边问树形图的数目
考虑多出来不合法的方案,一定是成环且包含新加入的边
对于一条路贡献就是∏d[i] [i∉path]
考虑不属于太不和谐,我们设s=∏d[i]
贡献就是s*∏d[i]^(-1) [i属于path],这样我们就可以dp了
这里学到了一个新知识,就是线性求出1~p-1对于p的逆元
首先1^(-1)≡1 (mod p)
对于范围内i,有ki+r=p
则ki+r≡0 (mod p) 同乘i^(-1)*r^(-1)
有kr^(-1)+i^(-1)≡0 (mod p)
i^(-1)≡-kr^(-1) (mod p)
则i^(-1)≡-[p div i]*(p mod i)^(-1) (mod p)
这样我们就可以递推了
1 const mo=1000000007; 2 3 type node=record 4 po,next:longint; 5 end; 6 7 var q,c,d,p,f:array[0..100010] of longint; 8 ni:array[0..200010] of longint; 9 e:array[0..200010] of node; 10 x0,y0,ans,i,len,n,m,x,y:longint; 11 12 procedure add(x,y:longint); 13 begin 14 inc(len); 15 e[len].po:=y; 16 e[len].next:=p[x]; 17 p[x]:=len; 18 end; 19 20 procedure shaker; 21 var i:longint; 22 begin 23 ni[1]:=1; 24 for i:=2 to m+1 do 25 ni[i]:=(-int64(mo div i)*int64(ni[mo mod i]) mod mo+mo) mod mo; 26 end; 27 28 procedure work; 29 var i,h,r,x,y:longint; 30 begin 31 f[y0]:=ans; 32 h:=1; 33 r:=0; 34 for i:=1 to n do 35 if d[i]=0 then 36 begin 37 inc(r); 38 q[r]:=i; 39 end; 40 41 while h<=r do 42 begin 43 x:=q[h]; 44 f[x]:=int64(f[x])*int64(ni[c[x]]) mod mo; 45 i:=p[x]; 46 while i<>0 do 47 begin 48 y:=e[i].po; 49 f[y]:=(f[y]+f[x]) mod mo; 50 dec(d[y]); 51 if d[y]=0 then 52 begin 53 inc(r); 54 q[r]:=y; 55 end; 56 i:=e[i].next; 57 end; 58 inc(h); 59 end; 60 end; 61 62 begin 63 readln(n,m,x0,y0); 64 for i:=1 to m do 65 begin 66 readln(x,y); 67 add(x,y); 68 inc(d[y]); 69 inc(c[y]); 70 end; 71 shaker; 72 ans:=1; 73 inc(c[y0]); 74 for i:=2 to n do 75 ans:=int64(ans)*int64(c[i]) mod mo; 76 if y0=1 then 77 begin 78 writeln(ans); 79 halt; 80 end; 81 work; 82 writeln((ans-f[x0]+mo) mod mo); 83 end.
时间: 2024-10-25 20:47:50