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找环)相关的知识,希望对你有一定的参考价值。
题意
有 [ 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)