time limit per test:2 seconds
memory limit per test:256 megabytes
You are given an array a1a_1a1,a2a_2a2,…,ana_nan and an array b1b_1b1,b2b_2b2,…,bnb_nbn.
For one operation you can sort in non-decreasing order any subarray a[l…r]a[l…r]a[l…r]
of the array aaa.
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 bbb
by applying this operation any number of times (possibly zero) to the array aaa.
Input
The first line contains one integer t(1≤t≤3⋅105)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⋅105)n(1≤n≤3⋅10^5)n(1≤n≤3⋅105).
The second line of each query contains nnn integers a1,a2,…,an(1≤ai≤n)a_1,a_2,…,a_n (1≤a_i≤n)a1,a2,…,an(1≤ai≤n).
The third line of each query contains nnn integers b1,b2,…,bn(1≤bi≤n)b_1,b_2,…,b_n (1≤bi≤n)b1,b2,…,bn(1≤bi≤n).
It is guaranteed that ∑n≤3⋅105∑n≤3⋅10^5∑n≤3⋅105 over all queries in a test.
Output
For each query print YESYESYES (in any letter case) if it is possible to obtain an array bbb and NONONO (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 a1…a5a_1…a_5a1…a5 , then aaa 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 a5…a6a5…a6a5…a6.
题意:
给定两个等长的数组a,ba,ba,b,定义操作为选取a中的一个区间让其变为升序,问是否存在若干次操作之后,a数组与b数组相同。
题解:
首先,我们先确定一个事情:我们将操作的区间长度设置为2。这样就可以像冒泡排序一样操作a序列了。
那么现在的问题就是,b序列是否是a序列冒泡排序中的一个状态。
首先我们知道,如果一个a[i]a[i]a[i]能被移动到数组的位置j(j<i)j(j<i)j(j<i)那么对于iii到jjj之间的所有数字,他们的值一定小于a[i]a[i]a[i]
那么我们顺序遍历bbb数组,对于每一个b[i]b[i]b[i]我们找到在aaa数组中最靠左边的等于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。这样做nnn次即可。这个操作我们可以用线段树来实现。
#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;
}