题解:CF2060G Bugged Sort
yingkeqian9217 · · 题解
有意思的简单题。
判定能否通过某种操作达到确定状态的题目,我们可以尝试进一步简化操作。显然每一列是
由于我们可以同时改变列内序和列间序,所以我们考虑如何只改变列间序(列内序)。事实上,对于两列
但是由于每次改变两列的列间序,所以一定只能列间序改变偶数列。
于是问题变成了若干对
考虑内部序,注意到对于线段有交的连通块,第一条线段的内部序定后,后面的实际上都已经确定,所以每次只能同时翻转一个连通块。假设我们已经排序,对于总次数的奇偶性,偶长块不改变,奇长块一定改变,所以要么初始为偶数,要么存在奇长块。
代码比 dp 好写一些。
#include<bits/stdc++.h>
#define maxn 210005
#define fi first
#define se second
using namespace std;
const int inf=1e9;
int n,id[maxn];
pair<int,int>p[maxn];
inline void solve(){
int sum=0;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&p[i].fi);
for(int i=1;i<=n;i++) scanf("%d",&p[i].se),id[i]=i;
for(int i=1;i<=n;i++) if(p[i].fi>p[i].se) swap(p[i].fi,p[i].se),sum^=1;
sort(id+1,id+n+1,[](int x,int y){return p[x]<p[y];});
int r=0,cnt=0,fl=0;
p[id[n+1]=n+1].fi=inf;
for(int it=1,i=id[it];it<=n+1;it++,i=id[it]){
if(p[i].fi<=r){
if(p[i].se<r) return puts("NO"),void();
r=p[i].se;
cnt^=1;
continue;
}
if(it!=1) fl|=cnt;
cnt=1,r=p[i].se;
}
puts(sum&&!fl?"NO":"YES");
}
signed main(){
signed T=1;
scanf("%d",&T);
while(T--) solve();
return 0;
}