【CF711D】Directed Roads(环,强连通分量)

题意:

  给一张N个点N条有向边的图,边可以逆向。问任意逆向若干条边使得这张图无环的方案数(mod 1e9+7)。

n<=200000

思路:三个样例给的好 找规律方便很多

        易得有N点的环有(2^n)-2中改法,除了不改和都改

        剩下的都是链,设除环外还有K个点,他们的总贡献就是2^k,因为都是一条边相连接怎么改也没有环

        CF上快速幂要写在外面不然会出现奇奇怪怪的CE

 1 const mo=1000000007;
 2 var head,vet,next,stack,low,dfn,b,s,flag:array[1..500000]of longint;
 3     n,tot,i,id,time,top,x,m:longint;
 4     ans,f,tmp:int64;
 5 
 6 procedure add(a,b:longint);
 7 begin
 8  inc(tot);
 9  next[tot]:=head[a];
10  vet[tot]:=b;
11  head[a]:=tot;
12 end;
13 
14 function min(x,y:longint):longint;
15 begin
16  if x<y then exit(x);
17  exit(y);
18 end;
19 
20 procedure dfs(u:longint);
21 var e,v:longint;
22 begin
23  flag[u]:=1;
24  inc(top); stack[top]:=u;
25  inc(time); dfn[u]:=time; low[u]:=time;
26  e:=head[u];
27  while e<>0 do
28  begin
29   v:=vet[e];
30   if flag[v]=0 then
31   begin
32    dfs(v);
33    low[u]:=min(low[u],low[v]);
34   end
35    else if s[v]=0 then low[u]:=min(low[u],low[v]);
36   e:=next[e];
37  end;
38  if dfn[u]=low[u] then
39  begin
40   inc(id); s[u]:=id; inc(b[id]);
41   while (top>0)and(stack[top]<>u) do
42   begin
43    s[stack[top]]:=id;
44    inc(b[id]);
45    stack[top]:=0;
46    dec(top);
47   end;
48   stack[top]:=0; dec(top);
49  end;
50 end;
51 
52 begin
53 
54  readln(n);
55  for i:=1 to n do
56  begin
57   read(x);
58   add(i,x);
59  end;
60  for i:=1 to n do
61   if flag[i]=0 then dfs(i);
62  m:=0;
63  for i:=1 to n do
64   if b[s[i]]=1 then m:=m+1;
65  ans:=1;
66  for i:=1 to id do
67   if b[i]>1 then
68   begin
69    f:=1; tmp:=2;
70    while b[i]>0 do
71    begin
72     if b[i] mod 2=1 then f:=f*tmp mod mo;
73     tmp:=tmp*tmp mod mo;
74     b[i]:=b[i] div 2;
75    end;
76    ans:=(ans*(f-2)) mod mo;
77   end;
78   ans:=(ans+mo) mod mo;
79   f:=1; tmp:=2;
80   while m>0 do
81   begin
82    if m mod 2=1 then f:=f*tmp mod mo;
83    tmp:=tmp*tmp mod mo;
84    m:=m div 2;
85   end;
86   ans:=ans*f mod mo;
87  writeln(ans);
88 
89 end.
原文地址:https://www.cnblogs.com/myx12345/p/5901640.html