CF1385G Columns Swaps-题解

· · 题解

CF1385G Columns Swaps-题解

题目分析

对于某个数:

那这个条件事实上是啥?类似 P9869 [NOIP2023] 三值逻辑(这个题用扩展状态表示某个位置取反),因为每个列要么被交换,要么不被交换,自然这里把每个列分成两个状态,用扩展域并查集实现。

做完上面,我们得到了若干两两配对的连通块,对每一对互补块(g[i] 和 g[i+n]):

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define db double
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
const int N=2e5+10;
int a[N];
int b[N];
int fa[N+N];
vector<int> w1[N];
vector<int> w2[N];

vector<int> g[N+N];

int find(int x)
{
    if(fa[x]==x) return fa[x];
    else return fa[x]=find(fa[x]);
}
void merge(int x,int y)
{
    x=find(x);
    y=find(y);
    fa[x]=y;
}
signed main()
{
    int sti=clock();

//  system("fc d.out e.out");
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int T;
    cin>>T;
    while(T--)
    {
        int n;
        cin>>n;
        for(int i=1;i<=2*n;i++)
        {
            fa[i]=i;
            g[i].clear();

        }
        for(int i=1;i<=n;i++)
        {
            w1[i].clear();
            w2[i].clear();
        }
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            w1[a[i]].push_back(i);
        }
        for(int i=1;i<=n;i++)
        {
            cin>>b[i];
            w2[b[i]].push_back(i);
        }

        bool fl=1;
        for(int i=1;i<=n;i++)
        {
            if(w1[i].size()==2)
            {
                int xx=w1[i][0];
                int yy=w1[i][1];
                merge(xx,yy+n);
                merge(xx+n,yy);
            }
            else if(w1[i].size()==1 && w2[i].size()==1)
            {
                int xx=w1[i][0];
                int yy=w2[i][0];
                merge(xx+n,yy+n);
                merge(xx,yy);
            }
            else if(w2[i].size()==2)
            {
                int xx=w2[i][0];
                int yy=w2[i][1];
                merge(xx,yy+n);
                merge(xx+n,yy);                 
            }
            else
            {
                cout<<-1<<"\n";
                fl=0;break;
            }
        }
        if(fl==0) continue;
        for(int i=1;i<=n;i++)
        {                   
            g[find(i)].push_back(i);
        }
        vector<int> ans;

        for(int i=1;i<=n;i++)
        {                                                                     
            if(g[i].size()<=g[i+n].size())
            {
                for(int v : g[i])
                {
                    ans.push_back(v);
                }                                                                                                                             
            }
            else
            {
                for(int v : g[i+n])
                {
                    ans.push_back(v);
                }                   
            }
        }
        cout<<ans.size()<<"\n";
        for(int i : ans)
        {
            cout<<i<<" ";
        }
        cout<<"\n";
    }
//  cerr<<1.0*(clock()-sti)/CLOCKS_PER_SEC<<endl;
    return 0;
}