题目链接: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. Tyvj——P1952 Easy

    http://www.tyvj.cn/p/1952 描述 某一天WJMZBMR在打osu~~~但是他太弱逼了,有些地方完全靠运气:(我们来简化一下这个游戏的规则有n次点击要做,成功了就是o,失败了就是 ...

  2. 洛谷——P1294 高手去散步

    P1294 高手去散步 题目背景 高手最近谈恋爱了.不过是单相思.“即使是单相思,也是完整的爱情”,高手从未放弃对它的追求.今天,这个阳光明媚的早晨,太阳从西边缓缓升起.于是它找到高手,希望在晨读开始 ...

  3. 笔记-迎难而上之Java基础进阶4

    内部类创建多线程 //匿名内部类创建多线程 public class InnerClassThread{ public static void main(String[] args){ //回忆一下之 ...

  4. Java中HashMap的初始容量设置

    根据阿里巴巴Java开发手册上建议HashMap初始化时设置已知的大小,如果不超过16个,那么设置成默认大小16: 集合初始化时, 指定集合初始值大小. 说明: HashMap使用HashMap(in ...

  5. 讯飞语音识别Android-Demo

    import java.io.UnsupportedEncodingException; import android.app.Activity; import android.os.Bundle; ...

  6. andriod打开摄像头和打开相册

    package com.example.yanlei.picture; import android.support.v7.app.AppCompatActivity; import android. ...

  7. Go -- LFU类(缓存淘汰算法)(转)

    1. LFU类 1.1. LFU 1.1.1. 原理 LFU(Least Frequently Used)算法根据数据的历史访问频率来淘汰数据,其核心思想是“如果数据过去被访问多次,那么将来被访问的频 ...

  8. python为不同的对象如何分配内存的小知识

    id方法的返回值就是对象的内存地址. python中会为每个出现的对象分配内存,哪怕他们的值完全相等(注意是相等不是相同).如执行a=2.0,b=2.0这两个语句时会先后为2.0这个Float类型对象 ...

  9. linux 中两个文档怎么对比内容是否一致

    可以用diff命令对比文档内容.[语法]: diff [参数] 文件1 文件2[说明]: 本命令比较两个文本文件,将不同的行列出来-b 将一串空格或TAB 转换成一个空格或TAB-e 生成一个编辑角本 ...

  10. angular - 配置package.json -3

    package.json 包含了所有的开发包以及全局包以及其它项目信息,我们这个项目需要用到 bootstrap,所以我们添加信息. 添加包信息以后,我们用 npm install 安装,npm包管理 ...