很多棵环套树。。。找环即可。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxv 200500 #define maxe 400500 #define mod 1000000007 using namespace std; int n,x,g[maxv],nume=1,pre[maxv],dis[maxv],ret=0,lop[maxv],sum=0; int s1[maxv],s2[maxv],t1=0,t2=0; long long ans=1; bool vis[maxv]; struct edge { int v,nxt; }e[maxe]; void addedge(int u,int v) { e[++nume].v=v; e[nume].nxt=g[u]; g[u]=nume; } void dfs(int x,int fath) { vis[x]=true; for (int i=g[x];i;i=e[i].nxt) { int v=e[i].v; if (!vis[v]) {pre[v]=i;dis[v]=dis[x]+1;dfs(v,x);} else { if (v==fath) { if ((i^1)==pre[x]) continue; else s1[++t1]=x,s2[++t2]=v; } else if (dis[v]<dis[x]) s1[++t1]=x,s2[++t2]=v; } } } long long f_pow(long long a,long long b) { long long an=1,base=a; while (b) { if (b&1) an=(an*base)%mod; base=(base*base)%mod; b>>=1; } return an%mod; } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d",&x); addedge(i,x);addedge(x,i); } for (int i=1;i<=n;i++) if (!vis[i]) dfs(i,-1); for (int i=1;i<=t1;i++) { int now=s1[i];ret=1; while (now!=s2[i]) { ret++; now=e[pre[now]^1].v; } lop[i]=ret; } for (int i=1;i<=t1;i++) { sum+=lop[i]; ans=(ans*(f_pow(2,lop[i])-2)%mod)%mod; } ans=(ans*f_pow(2,n-sum))%mod; printf("%I64d ",ans); return 0; }