题解:CF2254F Whiplash
关键结论:进行有限次题目所说的操作,等价于先对
我们可以通过以下三次操作实现对
-
选择
1 处的a_1 操作,得到a_1, a_2 \oplus a_1, \dots, a_{i} \oplus a_1, \dots, a_n \oplus a_1 -
选择
i 处的a_i \oplus a_1 操作,得到a_i, a_2 \oplus a_i, \dots, a_i \oplus a_1, \dots a_n \oplus a_i 。 -
选择
1 处的a_i 操作,得到a_i, a_2, \dots, a_1, \dots, a_n 。
至此我们交换了
所以问题转化为判断能否通过至多一次操作,使得
记
所以在
:::info[code]
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
int ttt, n, a[N], b[N];
int main(){
ios :: sync_with_stdio(false);
cin >> ttt;
while(ttt--){
cin >> n;
int s1 = 0, s2 = 0;
for(int i = 1; i <= n; i++) cin >> a[i], s1 ^= a[i];
for(int i = 1; i <= n; i++) cin >> b[i], s2 ^= b[i];
sort(a + 1, a + n + 1);
sort(b + 1, b + n + 1);
bool flag = 1;
for(int i = 1; i <= n; i++){
if(a[i] != b[i]){
flag = 0;
break;
}
}
if(flag){
cout << "YES\n";
continue;
}
int tmp = -1;
for(int i = 1; i <= n; i++)
if((s2 ^ b[i]) == s1) tmp = i;
if(tmp == -1){
cout << "NO\n";
continue;
}
for(int i = 1; i <= n; i++)
if(i != tmp) b[i] ^= b[tmp];
sort(b + 1, b + n + 1);
flag = 1;
for(int i = 1; i <= n; i++){
if(a[i] != b[i]){
flag = 0;
break;
}
}
if(flag) cout << "YES\n";
else cout << "NO\n";
}
return 0;
}
:::