time limit per test:2 seconds
memory limit per test:256 megabytes
You are given an array
a
1
a_1
a1,
a
2
a_2
a2,…,
a
n
a_n
an and an array
b
1
b_1
b1,
b
2
b_2
b2,…,
b
n
b_n
bn.
For one operation you can sort in non-decreasing order any subarray
a
[
l
…
r
]
a[l…r]
a[l…r]
of the array
a
a
a.
For example, if
a
=
[
4
,
2
,
2
,
1
,
3
,
1
]
a=[4,2,2,1,3,1]
a=[4,2,2,1,3,1] and you choose subbarray
a
[
2
…
5
]
a[2…5]
a[2…5], then the array turns into
[
4
,
1
,
2
,
2
,
3
,
1
]
[4,1,2,2,3,1]
[4,1,2,2,3,1].
You are asked to determine whether it is possible to obtain the array
b
b
b
by applying this operation any number of times (possibly zero) to the array
a
a
a.
Input
The first line contains one integer
t
(
1
≤
t
≤
3
⋅
1
0
5
)
t(1≤t≤3⋅10^5)
t(1≤t≤3⋅105) — the number of queries.
The first line of each query contains one integer
n
(
1
≤
n
≤
3
⋅
1
0
5
)
n(1≤n≤3⋅10^5)
n(1≤n≤3⋅105).
The second line of each query contains
n
n
n integers
a
1
,
a
2
,
…
,
a
n
(
1
≤
a
i
≤
n
)
a_1,a_2,…,a_n (1≤a_i≤n)
a1,a2,…,an(1≤ai≤n).
The third line of each query contains
n
n
n integers
b
1
,
b
2
,
…
,
b
n
(
1
≤
b
i
≤
n
)
b_1,b_2,…,b_n (1≤bi≤n)
b1,b2,…,bn(1≤bi≤n).
It is guaranteed that
∑
n
≤
3
⋅
1
0
5
∑n≤3⋅10^5
∑n≤3⋅105 over all queries in a test.
Output
For each query print Y E S YES YES (in any letter case) if it is possible to obtain an array b b b and N O NO NO (in any letter case) otherwise.
Example
Input
4
7
1 7 1 4 4 5 6
1 1 4 4 5 7 6
5
1 1 3 3 5
1 1 3 3 5
2
1 1
1 2
3
1 2 3
3 2 1
Output
YES
YES
NO
NO
Note
In first test case the can sort subarray a 1 … a 5 a_1…a_5 a1…a5 , then a a a will turn into [ 1 , 1 , 4 , 4 , 7 , 5 , 6 ] [1,1,4,4,7,5,6] [1,1,4,4,7,5,6], and then sort subarray a 5 … a 6 a5…a6 a5…a6.
题意:
给定两个等长的数组
a
,
b
a,b
a,b,定义操作为选取a中的一个区间让其变为升序,问是否存在若干次操作之后,a数组与b数组相同。
题解:
首先,我们先确定一个事情:我们将操作的区间长度设置为2。这样就可以像冒泡排序一样操作a序列了。
那么现在的问题就是,b序列是否是a序列冒泡排序中的一个状态。
首先我们知道,如果一个
a
[
i
]
a[i]
a[i]能被移动到数组的位置
j
(
j
<
i
)
j(j<i)
j(j<i)那么对于
i
i
i到
j
j
j之间的所有数字,他们的值一定小于
a
[
i
]
a[i]
a[i]
那么我们顺序遍历
b
b
b数组,对于每一个
b
[
i
]
b[i]
b[i]我们找到在
a
a
a数组中最靠左边的等于
b
[
i
]
b[i]
b[i]的
a
[
i
]
a[i]
a[i]
而且这个
b
[
i
]
b[i]
b[i]还要不能比它前面的,还未被选中的数字要大。如果存在这样的
a
[
i
]
a[i]
a[i]那么我们就选中它,否则直接输出NO。这样做
n
n
n次即可。这个操作我们可以用线段树来实现。
#include<bits/stdc++.h>
using namespace std;
struct seg{
int l,r,w;
}tr[1200004];
int n,a[300004],b[300004];
void build(int k,int l,int r){
tr[k].l=l;tr[k].r=r;
if(l==r){
tr[k].w=a[l];
return ;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
tr[k].w=min(tr[k<<1].w,tr[k<<1|1].w);
}
void modify(int k,int pos,int v){
int l=tr[k].l,r=tr[k].r;
if(l==r&&r==pos){
tr[k].w=v;
return ;
}
int mid=(l+r)>>1;
if(pos<=mid)modify(k<<1,pos,v);
else modify(k<<1|1,pos,v);
tr[k].w=min(tr[k<<1].w,tr[k<<1|1].w);
}
int query(int k,int v){
int l=tr[k].l,r=tr[k].r;
if(l==r){
if(tr[k].w==v)return r;
else return -1;
}
int mid=(l+r)>>1;
if(tr[k<<1].w<=v)return query(k<<1,v);
else return query(k<<1|1,v);
}
int w33ha(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n;i++)scanf("%d",&b[i]);
build(1,1,n);
for(int i=1;i<=n;i++){
int now=query(1,b[i]);
if(now==-1)return puts("NO"),0;
modify(1,now,n+1);
}
puts("YES");
return 0;
}
int main(){
int T;scanf("%d",&T);
while(T--)w33ha();
return 0;
}