题目描述
Alice 有一个 2×n2×n 的数字阵列,也就是两行,每行 nn 个数的矩阵。因为排列的性质是优美的,所以 Alice 让每行初始都是 1∼n1∼n 的排列。
静止的数阵再优美也会看腻,所以 Alice 尝试对这个数阵做最简单的变换:交换一列中的两个数字。当然,经过若干次交换后,Alice 仍然希望这个数阵的两行都是 1∼n1∼n 的排列。
Alice 每天都希望看到不同的优美的数阵,所以请算出通过任意次(可以是 00 次)交换一列中的两个数字,能造出多少个不同的优美的数阵。称两个优美的数阵不同,当且仅当存在某一列在其中一个数阵中最终执行了交换,而另一个数阵没有。
由于答案可能很大,你只需要输出其对 109+7109+7 取模后的值。
输入格式
第一行一个整数 TT 表示数据组数,对于每组数据:
第一行一个整数 nn。
第二、三行每行 nn 个数字 pi,jpi,j,分别表示数阵两行的元素。
输出格式
对于每组数据,输出一行一个整数表示答案对 109+7109+7 取模后的值。
数据范围
对于 30%30% 的数据,1≤T≤101≤T≤10,2≤n≤182≤n≤18。
对于 60%60% 的数据,1≤T≤101≤T≤10,2≤n≤10002≤n≤1000。
对于 100%100% 的数据,1≤T≤1041≤T≤104,2≤n≤4×1052≤n≤4×105,∑n≤4×105∑n≤4×105,1≤pi,j≤n1≤pi,j≤n,p1,p2p1,p2 分别构成 1∼n1∼n 的排列。
样例数据
输入:
2
4
1 2 3 4
4 3 2 1
5
1 3 5 2 4
2 4 1 3 5
输出:
4
2
说明:
样例解释:对于第二组数据,只有不交换和同时交换每一列中的两个数字才能使得最终得到的数阵是优美的。
详见代码:
#include <bits/stdc++.h>
using namespace std;
int a[400005];
int b[400005];
int c[400005];
int f(int x)
{
int mod = 1e9 + 7;
if (x == 0) return 1;
long long ret = f(x / 2);
if (x % 2 == 0) return ret * ret % mod;
else return 2 * ret * ret % mod;
}
int main()
{
int t, n, q;
cin >> t;
while(t--)
{
cin >> n;
for(int i = 1; i <= n; i++)
{
cin >> a[i];
}
for(int i = 1; i <= n; i++)
{
cin >> b[i];
}
for(int i = 1; i <= n; i++)
{
c[a[i]] = b[i];
}
int cnt = 0;
for(int i = 1; i <= n; i++)
{
if (c[i] != 0)
{
cnt++;
int t = c[i];
int s = c[i];
while(c[t] != s)
{
int x = c[t];
c[t] = 0;
t = x;
}
}
}
cout << f(cnt) << endl;
}
return 0;
}