Codeforces LATOKEN Round 1 (Div. 1 + Div. 2) C. Little Alawn‘s Puzzle(dfs找环)

Posted issue是fw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces LATOKEN Round 1 (Div. 1 + Div. 2) C. Little Alawn‘s Puzzle(dfs找环)相关的知识,希望对你有一定的参考价值。

LINK

题意

[ 1 , n ] [1,n] [1,n]的两个排列分别为数组 a a a和数组 b b b

现在对于每个 i ∈ [ 1 , n ] i\\in[1,n] i[1,n]都可以选择交换或不交换 a i a_i ai b i b_i bi

问交换后, a , b a,b a,b仍然是一个排列的方案数.


试想我们交换 a 1 , b 1 a_1,b_1 a1,b1

那么数组 a a a中会出现两个数字 b 1 b_1 b1

这是不允许发生的,所以需要在数组 a a a中找到另一个值为 b 1 b_1 b1的位置 x x x

然后交换 a x , b x a_x,b_x ax,bx,然后 b x b_x bx又会在 a a a中出现两次…

一直这样往下,直到 b x = = a 1 b_x==a_1 bx==a1,此时形成一个闭环

那么交换这个环中所有位置仍然满足条件,当然也可以不换

于是设环数为 z z z,方案是 2 z 2^z 2z

#include <iostream>
using namespace std;
const int maxn = 4e5+10;
const int mod = 1e9+7;
int vis[maxn],pos[maxn],ans,chu,n;
int a[maxn],b[maxn];
void dfs(int u)
{
	//a[i]��b[i]����� 
	vis[u] = 1;
	//��һ����Ҫ��pos[b[i]]λ�ý���λ��
	if( b[u]==chu ){ ans++; return; }
	dfs( pos[b[u]] ); 
}
int quick(int x,int n)
{
	int ans = 1;
	for( ; n ; n>>=1,x=1ll*x*x%mod )
		if( n&1 )	ans = 1ll*ans*x%mod;
	return ans;
}
int main()
{
	int t; cin >> t;
	while( t-- )
	{
		ans = 0;
		cin >> n;
		for(int i=1;i<=n;i++)	cin >> a[i];
		for(int i=1;i<=n;i++)	cin >> b[i], pos[a[i]] = i;
		for(int i=1;i<=n;i++)
		{
			if( vis[i] )	continue;
			chu = a[i];
			dfs( i );
		}
		cout << quick(2,ans)%mod << endl;
		for(int i=1;i<=n;i++)	vis[i] = 0;
	}
	return 0;
} 

以上是关于Codeforces LATOKEN Round 1 (Div. 1 + Div. 2) C. Little Alawn‘s Puzzle(dfs找环)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces LATOKEN Round 1 (Div. 1 + Div. 2)

Codeforces LATOKEN Round 1 (Div. 1 + Div. 2) E. Lost Array(构造)

Codeforces LATOKEN Round 1 (Div. 1 + Div. 2) B. Histogram Ugliness(贪心)

Codeforces LATOKEN Round 1 (Div. 1 + Div. 2) D. Lost Tree(交互,二分/图,思维)

D. Lost Tree树的二分图性质——Codeforces LATOKEN Round 1 (Div. 1 + Div. 2)

D. Lost Tree树的二分图性质——Codeforces LATOKEN Round 1 (Div. 1 + Div. 2)