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));
}
}

浙公网安备 33010602011771号