Swaps Again
Problem Description
Ayush, Ashish and Vivek are busy preparing a new problem for the next Codeforces round and need help checking if their test cases are valid.
Each test case consists of an integer n and two arrays a and b, of size n n n. If after some (possibly zero) operations described below, array a can be transformed into array b, the input is said to be valid. Otherwise, it is invalid.
An operation on array a is:
- select an integer k k k ( 1 ≤ k ≤ ⌊ n 2 ⌋ 1≤k≤⌊\frac{n}{2}⌋ 1≤k≤⌊2n⌋)
- swap the prefix of length k with the suffix of length k k k
For example, if array a initially is {1,2,3,4,5,6}, after performing an operation with k = 2 k=2 k=2, it is transformed into {5,6,3,4,1,2}.
Given the set of test cases, help them determine if each one is valid or invalid.
Input
The first line contains one integer t t t ( 1 ≤ t ≤ 500 1≤t≤500 1≤t≤500) — the number of test cases. The description of each test case is as follows.
The first line of each test case contains a single integer n n n ( 1 ≤ n ≤ 500 1≤n≤500 1≤n≤500) — the size of the arrays.
The second line of each test case contains n integers a 1 a_1 a1, a 2 a_2 a2, …, a n a_n an ( 1 ≤ a i ≤ 1 0 9 1≤a_i≤10^9 1≤ai≤109) — elements of array a.
The third line of each test case contains n integers b 1 b_1 b1, b 2 b_2 b2, …, b n b_n bn ( 1 ≤ b i ≤ 1 0 9 1≤b_i≤10^9 1≤bi≤109) — elements of array b.
Output
For each test case, print “Yes” if the given input is valid. Otherwise print “No”.
You may print the answer in any case.
Sample Input
5
2
1 2
2 1
3
1 2 3
1 2 3
3
1 2 4
1 3 4
4
1 2 3 2
3 1 2 2
3
1 2 3
1 3 2
Sample Output
yes
yes
No
yes
No
题意
对于一个长度为n的序列,可以执行以下操作:
选择一个正整数k(
1
≤
k
≤
⌊
n
2
⌋
1≤k≤⌊\frac{n}{2}⌋
1≤k≤⌊2n⌋);
将序列前k个与后k个数交换位置,换句话说就是对于
1
≤
i
≤
k
1\le i \le k
1≤i≤k, swap(
a
i
a_i
ai,
a
n
−
k
+
i
a_{n-k+i}
an−k+i).
有两个长度相同的数组a,b。能对a进行任意次上述操作,能否使两个数组相等。
题解
观察后可以发现数组原下标为
(
i
,
n
+
1
−
i
)
(i,n+1-i)
(i,n+1−i)的二元组,无论怎么交换,两者的下标和恒为
n
+
1
n+1
n+1,两者的前后关系可变。
将数组中间位置作为对称轴,从对称轴向边界考虑。当考虑到
(
b
i
,
b
n
+
1
−
i
)
(b_i,b_{n+1-i})
(bi,bn+1−i)时,查找数组a中是否有值相同的二元组(顺序无所谓,且
i
+
1
i+1
i+1到对称轴的元素已确定,不再考虑)。设此时找到一个满足条件的二元组,下标为
j
j
j,可令
k
=
j
k = j
k=j执行操作,则次二元组移动至(1,n)的位置(若两者顺序相反,执行一次
k
=
1
k = 1
k=1操作即可),然后再执行
k
=
i
k= i
k=i操作,即可令
b
i
=
a
i
b_i = a_i
bi=ai,
b
n
+
1
−
i
=
a
n
+
1
−
i
b_{n+1-i} = a_{n+1-i}
bn+1−i=an+1−i。
分别对两个数组求出二元组,判断能否一一对应即可。
#include<stdio.h>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<iterator>
#define dbg(x) cout<<#x<<" = "<<x<<endl;
#define INF 0x3f3f3f3f
#define eps 1e-6
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 200100;
const int mod = 1000000007;
struct node{
int a, b;
}p1[maxn], p2[maxn];
int a[maxn], b[maxn];
bool cmp(node a, node b);
int main()
{
int t, n, m, i, j, k, sig;
scanf("%d", &t);
while(t--)
{
sig = 1;
scanf("%d", &n);
m = n/2;
for(i=0;i<n;i++)
scanf("%d", &a[i]);
for(i=0;i<n;i++)
scanf("%d", &b[i]);
if(n%2 && a[m] != b[m])sig = 0;
for(i=0;i<m;i++){
p1[i].a = a[i];
p1[i].b = a[n-1-i];
if(p1[i].a > p1[i].b)swap(p1[i].a, p1[i].b);
p2[i].a = b[i];
p2[i].b = b[n-1-i];
if(p2[i].a > p2[i].b)swap(p2[i].a, p2[i].b);
}
sort(p1, p1+m, cmp);
sort(p2, p2+m, cmp);
for(i=0;i<m;i++)
if(p1[i].a != p2[i].a || p1[i].b != p2[i].b)sig = 0;
if(sig)printf("Yes\n");
else printf("No\n");
}
return 0;
}
bool cmp(node a, node b)
{
if(a.a == b.a)return a.b < b.b;
return a.a < b.a;
}