CF1534C

题目简化和分析:

涉及算法:并查集

为什么要使用并查集:

  • 因为交换只能是列交换,并且保证不与别的重复
  • 我们通过观察题目发现,某些列之间互为限制关系
  • 即如果某列序列排序方式固定,则被限制的列也为固定的
  • 此时我们会发现只有两种(一个互相限制的集合列)

既然如此,我们将这每个集合看作为一个联通分量。
用并查集枚举有几个连通分量。
特别的,一列中的两个数肯定互相限制。

如果我们有 \(ans\) 个联通分量。
则答案为 \(2^{ans}\)

注意:一定要开 long long

Solution:

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
#define int long long
const int N=4e5+50;
const int mod=1e9+7;
int t,n;
int p[N],a[N],b[N];
int find(int x){
	if(x!=p[x]) return p[x]=find(p[x]);
	return p[x]; 
}
int qbow(int a,int b,int m)
{
    ll ans=1;
    while(b>0)
    {
        if(b%2!=0)
            ans=ans*a%m;
        a=a*a%m;
        b=b>>1;  
    }
    ans %= m;
    return ans;
}
signed main()
{
	scanf("%lld",&t);
	while(t--){
		scanf("%lld",&n);
		for(int i=1;i<=n;++i) scanf("%lld",&a[i]),p[i]=i;
		for(int i=1;i<=n;++i) {
			scanf("%lld",&b[i]);
			int fx=find(a[i]),fy=find(b[i]);
			if(fx!=fy){
				p[fx]=fy;
			}
		}
		int ans=0;
		for(int i=1;i<n;++i){
			int fx=find(i),fy=find(i+1);
			if(fx!=fy){
				ans++;
				p[fx]=fy;
			}
		}
		printf("%lld\n",qbow(2,ans+1,mod));
	}
}
posted @ 2022-08-06 15:14  RVG  阅读(45)  评论(0)    收藏  举报