Codeforces Round #369 (Div. 2) D. Directed Roads dfs求某个联通块的在环上的点的数量

D. Directed Roads

ZS the Coder and Chris the Baboon has explored Udayland for quite some time. They realize that it consists of n towns numbered from 1to n.

There are n directed roads in the Udayland. i-th of them goes from town i to some other town ai (ai ≠ i). ZS the Coder can flip the direction of any road in Udayland, i.e. if it goes from town A to town B before the flip, it will go from town B to town A after.

ZS the Coder considers the roads in the Udayland confusing, if there is a sequence of distinct towns A1, A2, ..., Ak (k > 1) such that for every 1 ≤ i < k there is a road from town Ai to town Ai + 1 and another road from town Ak to town A1. In other words, the roads are confusing if some of them form a directed cycle of some towns.

Now ZS the Coder wonders how many sets of roads (there are 2n variants) in initial configuration can he choose to flip such that after flipping each road in the set exactly once, the resulting network will not be confusing.

Note that it is allowed that after the flipping there are more than one directed road from some town and possibly some towns with no roads leading out of it, or multiple roads between any pair of cities.

Input

The first line of the input contains single integer n (2 ≤ n ≤ 2·105) — the number of towns in Udayland.

The next line contains n integers a1, a2, ..., an (1 ≤ ai ≤ n, ai ≠ i), ai denotes a road going from town i to town ai.

Output

Print a single integer — the number of ways to flip some set of the roads so that the resulting whole set of all roads is not confusing. Since this number may be too large, print the answer modulo 109 + 7.

Examples

input

32 3 1

output

6

Note

Consider the first sample case. There are 3 towns and 3 roads. The towns are numbered from 1 to 3 and the roads are  initially. Number the roads 1 to 3 in this order.

The sets of roads that ZS the Coder can flip (to make them not confusing) are {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}. Note that the empty set is invalid because if no roads are flipped, then towns 1, 2, 3 is form a directed cycle, so it is confusing. Similarly, flipping all roads is confusing too. Thus, there are a total of 6 possible sets ZS the Coder can flip.

The sample image shows all possible ways of orienting the roads from the first sample such that the network is not confusing.

题意

  n个点得图

  给你n条边,a[i] 表示 i指向a[i]

  现在你可以改变某些边的方向是的 图中不存在环

  问你有多少种方案

题解:

  总共有2^n

  对于这个图,我们视为无向。

  我们要明白 是由多个联通块 组成的 联通块中有可能存在环

  那么定义一个 联通快 上 在环上的 点数是 num , 这个联通块有all个点,之后我们给定方向,利用num,all我们就可以求出 这个联通块不存在环的 方案数了

  那么 对于答案 就是所有联通快不存在环 的 方案数 的乘积

 

#include<bits/stdc++.h>
using namespace std;

#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair

typedef long long LL;
const long long INF = 1e18;
const double Pi = acos(-1.0);
const int N = 2e5+10, M = 1e6+11, inf = 2e9, mod = 1e9+7;

int n,mx = -1,f[N],al,num;
int deep[N],vis[N];
vector<int >G[N];
void add(int u,int v){
    G[u].push_back(v);
}

LL quick_pow(LL x,LL p) {
    if(!p) return 1;
    LL ans = quick_pow(x,p>>1);
    ans = ans*ans%mod;
    if(p & 1) ans = ans*x%mod;
    return ans;
}

void dfs(int u,int fa,int dep) {
        al++;
        deep[u] = dep;
        vis[u] = 1;
        for(int i = 0; i < G[u].size(); ++i) {
            int to = G[u][i];
            if(!vis[to])dfs(to,u,dep+1);else if(to!=fa) num = (abs(deep[to] - deep[u]) + 1);
        }
}
LL in[N];
int main() {
        LL ans = 1;
        in[0] = 1;
        scanf("%d",&n);
        for(int i = 1; i < N; ++i) in[i] = 1LL * in[i-1] * 2 % mod;

        for(int i = 1; i <= n; ++i) {scanf("%d",&f[i]);add(i,f[i]);add(f[i],i);}

        for(int i = 1; i <= n; ++i) {
            al = num = 0;
            if(vis[i]) continue;
            dfs(i,0,0);
            if(al == 2) num = 2;
            ans = (ans * (in[num]-2LL) % mod * in[al-num]) % mod;
        }
        printf("%I64d\n",(ans+mod) % mod);
        return 0;
}
时间: 2024-10-12 04:40:58

Codeforces Round #369 (Div. 2) D. Directed Roads dfs求某个联通块的在环上的点的数量的相关文章

Codeforces Round #369 (Div. 2)-D Directed Roads

题目大意:给你n个点n条边的有向图,你可以任意地反转一条边的方向,也可以一条都不反转,问你有多少种反转的方法 使图中没有环. 思路:我们先把有向边全部变成无向边,每个连通图中肯定有且只有一个环,如果这个连通图里边有n个点,环由m个元素 构成,那么这个连通图的反转方法数为,(2^(n-m)) * (2^m-2),然后将所有连通图的种数乘到一起就好啦.具体求圆环由几 个点组成看代码. ps:最后算ans的时候忘了加括号,debug了一个小时QAQ. #include<bits/stdc++.h>

Codeforces Round #369 (Div. 2) C. Coloring Trees(dp)

题目链接:Codeforces Round #369 (Div. 2) C. Coloring Trees 题意: 有n个树,每个树有一个颜色,如果颜色值为0,表示没有颜色,一共有m个颜色,第j种颜色涂第i棵树需要花费pij,颜色一样且相邻的分为一组 现在要将所有颜色为0的树涂上颜色,使得这些树恰好可以分为k组,问最小的花费 题解: 考虑dp[i][j][k],表示考虑第i棵树涂第j种颜色,当前分为k组的最小花费,然后状态转移看代码,注意的是dp的初始状态 1 #include<bits/std

Codeforces Round #427 (Div. 2) D. Palindromic characteristics(Manacher求回文串)

题目链接:Codeforces Round #427 (Div. 2) D. Palindromic characteristics 题意: 给你一个串,定义k-th回文串,让你求每个k-th的数量. 题解: manacher处理好后做一下dp就行了. 当然也可以直接dp不用manacher. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 5 cons

Codeforces Round #369 (Div. 2) ABCD

A. Bus to Udayland 题解: 水,看样例就知道题意了 代码: #include<bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define se second #define fs first #define ll long long #define CLR(x) memset(x,0,sizeof x) #define MC(x,y) memcpy(x,y,size

Codeforces Round #369 (Div. 2)

A题,水题,暴力找即可. B题,水题,但是需要注意n=1的情况. C题,dp.虽然是个水dp,但是我还是没能够自己独立的写出来.= =太菜了!代码如下: 1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #include <iostream> 5 using namespace std; 6 const int N = 100 + 5; 7 typedef long lon

Codeforces Round #302 (Div. 2) D. Destroying Roads 最短路 删边

题目:有n个城镇,m条边权为1的双向边让你破坏最多的道路,使得从s1到t1,从s2到t2的距离分别不超过d1和d2. #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <queue> #include <stack> #in

Codeforces Round #360 (Div. 1)A (二分图&dfs染色)

题目链接:http://codeforces.com/problemset/problem/687/A 题意:给出一个n个点m条边的图,分别将每条边连接的两个点放到两个集合中,输出两个集合中的点,若不可能则输出-1: 思路:通过画图我们不难发现,图中没有出现长度为奇数的环则是可行的,反之则是不行的.那么现在我们只需判断有木有长度为偶数的环即可. 对于这点我们可以直接用dfs搜索+染色,对于当前标记为1的点,我们将其所有儿子标记为2, 对于当前标记为2的点,将其所有儿子标记为1,若出现某个节点的标

Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+树状数组

C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/problem/C Description Iahub likes trees very much. Recently he discovered an interesting tree named propagating tree. The tree consists of n nodes numb

Codeforces Round #595 (Div. 3)B2 简单的dfs

原题 https://codeforces.com/contest/1249/problem/B2 这道题一开始给的数组相当于地图的路标,我们只需对每个没走过的点进行dfs即可 #include <bits/stdc++.h> using namespace std;const int maxn=2e5+20;int a[maxn],b[maxn],c[maxn];int dfs(int pos,int step){//传递坐标与步数 if(b[pos]==1){//再次遇到b[pos],返回