[codeforces 1187D]Subarray Sorting

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[lr]
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[25], 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(1t3105) — 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(1n3105).
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(1ain).
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(1bin).
It is guaranteed that ∑ n ≤ 3 ⋅ 1 0 5 ∑n≤3⋅10^5 n3105 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 a1a5 , 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 a5a6.

题意:
给定两个等长的数组 a , b a,b a,b,定义操作为选取a中的一个区间让其变为升序,问是否存在若干次操作之后,a数组与b数组相同。
题解:
首先,我们先确定一个事情:我们将操作的区间长度设置为2。这样就可以像冒泡排序一样操作a序列了。
那么现在的问题就是,b序列是否是a序列冒泡排序中的一个状态。
首先我们知道,如果一个 a [ i ] a[i] a[i]能被移动到数组的位置 j ( j &lt; i ) j(j&lt;i) jj<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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值