题目链接:http://codeforces.com/problemset/problem/711/D

D. Directed Roads
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

ZS the Coder and Chris the Baboon has explored Udayland for quite some time. They realize that it consists of n towns numbered from 1 to 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
3
2 3 1
output
6
input
4
2 1 1 1
output
8
input
5
2 4 2 5 3
output
28
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.

题解:

1.根据题意, n个点共有n条边。那么表明每个连通块中, 有且仅有一个环, 且这个环可能还有一些“线丝”挂在上面。

2.首先对于一个连通块而言, 可分为环部分和线丝部分:对于环部分,如果有k个点, 那么有(1<<k)-2种情况可以去环。(-2是减去所有都flip或者所有都不flip这两种情况,因为这两种情况都不能 去环), 对于线丝部分, 他们的状态对环没有影响,假设线丝有t个点,那么状态数为1<<t。

最后将每个连通块的环部分和线丝部分的状态数相乘, 即为答案。

找环问题:

1.group[]数组记录当前点时是在哪一次的dfs中访问到的。vis[]记录当前点在这次dfs中是第几个被访问的元素。

2.在dfs的过程中, 当遇到被访问过的元素时: 如果它的group[i]为这次dfs所标记的, 那么表明这次dfs构成了环; 如果group[i]为之前dfs所标记的, 那么表明这次dfs出来的是线丝(遇到的连通块必定有环。因为:假设无环,那么就可以dfs出环了,说明假设不成立)。

代码如下:

 #include<bits/stdc++.h>
#define ms(a, b) memset((a), (b), sizeof(a))
using namespace std;
typedef long long LL;
const double eps = 1e-;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int maxn = 2e5+; int n, a[maxn];
int vis[maxn], group[maxn];
LL ans; LL qpow(LL x, LL y)
{
LL s = ;
while(y)
{
if(y&) s = (s*x)%mod;
x = (x*x)%mod;
y >>= ;
}
return s;
} void dfs(int k, int id, int cnt) //dfs出环, 或者dfs出线丝
{
vis[k] = cnt;
group[k] = id; if(vis[a[k]]) //遇到了被访问过的元素
{
if(group[a[k]]==id) //dfs出环
{
ans *= qpow(,cnt-vis[a[k]]+)-, ans %= mod; //环的部分
ans *= qpow(, vis[a[k]]-), ans %= mod; // 环之外的那条线
}
else ans *= qpow(,cnt), ans %= mod; //dfs出线丝
}
else dfs(a[k], id, cnt+);
} int main()
{
scanf("%d",&n);
for(int i = ; i<=n; i++)
scanf("%d",&a[i]); ans = ;
ms(vis,);
ms(group,);
for(int i = ; i<=n; i++)
if(!vis[i])
dfs(i,i,); printf("%lld\n", ans);
}

Codeforces Round #369 (Div. 2) D. Directed Roads —— DFS找环 + 快速幂的更多相关文章

  1. 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. The ...

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

    D. Directed Roads time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  3. Codeforces Round #369 (Div. 2) D. Directed Roads 数学

    D. Directed Roads 题目连接: http://www.codeforces.com/contest/711/problem/D Description ZS the Coder and ...

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

    题目大意:给你n个点n条边的有向图,你可以任意地反转一条边的方向,也可以一条都不反转,问你有多少种反转的方法 使图中没有环. 思路:我们先把有向边全部变成无向边,每个连通图中肯定有且只有一个环,如果这 ...

  5. Codeforces Round #307 (Div. 2) D. GukiZ and Binary Operations 矩阵快速幂优化dp

    D. GukiZ and Binary Operations time limit per test 1 second memory limit per test 256 megabytes inpu ...

  6. Codeforces Round #209 (Div. 2)A贪心 B思路 C思路+快速幂

    A. Table time limit per test 1 second memory limit per test 256 megabytes input standard input outpu ...

  7. CodeForces 711D Directed Roads (DFS找环+组合数)

    <题目链接> 题目大意: 给定一个$n$条边,$n$个点的图,每个点只有一条出边(初始状态),现在能够任意对图上的边进行翻转,问你能够使得该有向图不出先环的方案数有多少种. 解题分析: 很 ...

  8. Codeforces Round #302 (Div. 2) D - Destroying Roads 图论,最短路

    D - Destroying Roads Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/544 ...

  9. Codeforces Round #369 (Div. 2)---C - Coloring Trees (很妙的DP题)

    题目链接 http://codeforces.com/contest/711/problem/C Description ZS the Coder and Chris the Baboon has a ...

随机推荐

  1. 期望DP初步

    感觉期望DP这种东西像是玄学- 主要总结说一点基础性的东西, 或许对于理解题目的做法会有一点帮助. 首先是关于独立事件, 互斥事件的概念. 通俗地说, 就是对于两个事件A, B, 假如满足发生了其中一 ...

  2. 321. Create Maximum Number

    /* * 321. Create Maximum Number * 2016-7-6 by Mingyang */ public int[] maxNumber(int[] nums1, int[] ...

  3. "visual studio 2012 安装引擎拒绝访问" 错误的解决

    首先,我们看一下错误的具体提示,如下图所示: 这个错误,是我安装了那么多年Visual Studio的经历中,第一次遇到.太恶心了,昨天一直安装失败,导致后续其它软件的安装一再拖延.目前网上的解决方案 ...

  4. Windows10下Apache2.4配置Django

    开发环境 Windows 10 x64 Apache 2.4 x64 Python 2.7.11 x64 Django 1.9.6+ 下载和安装mod_wsgi 到 http://download.c ...

  5. hdu 2842(矩阵高速幂+递推)

    题意:一个中国环的游戏,规则是一个木棒上有n个环.第一个环是能够任意放上或拆下的,剩下的环x假设想放上或拆下必须前一个环x-1是放上的且前x-2个环所有是拆下的,问n个环最少多少次操作能够所有拆掉. ...

  6. Swift中的switch 和 do while

    switch后面的()能够省略 OC中的switch假设没有break就会穿透(依次运行),在Swift中不会穿透(可理解默认就有break) OC中入股要在case中定义变量,必要要加上{}确定作用 ...

  7. Pycharm下HTMLTestRunner不生成测试报告

    网上搜索资料,最终找到了本次解决的方案: 1.修改Edit Configurations... 2.将测试脚本从Python tests中删除,再Python下新增脚本,这样就不会运行自带的unitt ...

  8. h5的复制功能

    js+html5实现复制文字按钮 <div> <input type="text" name="guanfangaddress" id=&qu ...

  9. EasyDarwin开源流媒体服务器性能瓶颈分析及优化方案设计

    EasyDarwin现有架构介绍 EasyDarwin的现有架构对网络事件的处理是这样的,每一个Socket连接在EasyDarwin内部的对应存在形式就是一个Session,不论是RTSP服务对应的 ...

  10. Jquery 实现标签切换效果

    1.效果图 2.HTML代码如下 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> & ...