上海计算机学会2025年2月月赛C++丙组T4数阵交换

数阵交换

内存限制: 512 Mb时间限制: 1000 ms

题目描述

Alice 有一个 2×n 的数字阵列,也就是两行,每行 n 个数的矩阵。因为排列的性质是优美的,所以 Alice 让每行初始都是 1∼n 的排列。

静止的数阵再优美也会看腻,所以 Alice 尝试对这个数阵做最简单的变换:交换一列中的两个数字。当然,经过若干次交换后,Alice 仍然希望这个数阵的两行都是 1∼n 的排列。

Alice 每天都希望看到不同的优美的数阵,所以请算出通过任意次(可以是 0 次)交换一列中的两个数字,能造出多少个不同的优美的数阵。由于答案可能很大,你只需要输出其对 10^9+7 取模后的值。

输入格式

第一行一个整数 T 表示数据组数,对于每组数据:

第一行一个整数 n。

第二、三行每行 n 个数字 pi,j​,分别表示数阵两行的元素。

输出格式

对于每组数据,输出一行一个整数表示答案对 10^9+7 取模后的值。

数据范围

对于 30% 的数据,1≤T≤10,2≤n≤18。

对于 60% 的数据,1≤T≤10,2≤n≤1000。

对于 100% 的数据,1≤T≤10^4,2≤n≤4×10^5,∑n≤4×10^5,1≤pi,j≤n,p1,p2​ 分别构成 1∼n 的排列。

样例数据

 输入:
2
4
1 2 3 4
4 3 2 1
5
1 3 5 2 4
2 4 1 3 5
输出:
4
2
说明:
样例解释:对于第二组数据,只有不交换和同时交换每一列中的两个数字才能使得最终得到的数阵是优美的。

解析:

如果想要交换完的两个行元素都是1到n的全排列,那么交换的数字就必须全部相同,

则对于对于上下两行中数字相同的列,或者一组列,数字集合相同。

找出多少组这样的集合,交换方法就是2的多少次幂。

这样的组合都是成环存在的,所以只要找到有多少个这样的环,就能求出答案,详见代码:

#include <bits/stdc++.h>
using namespace std;
int a[400005];//第一列
int b[400005];//第二列
int c[400005];//c[i]表示第一列第i个位置对应的第二列的数值
int f(int x) {//2的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数组
            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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长春高老师信奥工作室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值