codeforces 711D Directed Roads

Posted on 2016-10-04 20:51  ziliuziliu  阅读(140)  评论(0)    收藏  举报

很多棵环套树。。。找环即可。

#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\n",ans);
    return 0;
}