题意:
给一张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.