CSU 2019暑假集训 Subarray Sorting

题目链接:http://codeforces.com/problemset/problem/1187/D

 

题目:

You are given an array a1,a2,,an and an array b1,b2,,bn

.

For one operation you can sort in non-decreasing order any subarray a[lr]

of the array a

.

For example, if a=[4,2,2,1,3,1]

and you choose subbarray a[25], then the array turns into [4,1,2,2,3,1]

.

You are asked to determine whether it is possible to obtain the array b

by applying this operation any number of times (possibly zero) to the array a.

 

Input

The first line contains one integer t (1t3105) — the number of queries.

The first line of each query contains one integer n(1n3105).

The second line of each query contains n

integers a1,a2,,an (1ain).

The third line of each query contains n

integers b1,b2,,bn (1bin).

It is guaranteed that n310over all queries in a test.

Output

For each query print YES (in any letter case) if it is possible to obtain an array b and 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 a1a5, then a will turn into [1,1,4,4,7,5,6], and then sort subarray a5a6.

思路

我一开始用的就是比较暴力的方法,就是遍历b数组,与a数组进行比较,如果相等,则统计前面一段数据的数值的个数,如果相等且数组b是不降序,就开始下一段,如果不等且步数数组末尾,就接着比较。这个方法看起来还不错,但是其实是错误的,因为有这种情况:

7

1 4 1 7 5 4 6

1 1 4 5 4 7 6

这个是output是YES。先是4 1排序,然后7 5排序,然后7 4排序,而用我这个方法就不对。

其实它是用线段树做的,线段树中保存数组a的数据,保存区间的最小值,也是遍历b数组,在线段树中寻找,保证b在区间是不降序。

AC代码:

/*用线段树保存数组a,数组b的每个数据都去线段树中寻找,由于树中保存的是最小值,每找到一个数据,就对该值最大化,如果b中某一个数比它后面的数大,
由于树中保存的是最小的数,最后就不能找到该数,这说明无法通过区间排序形成数组b  
*/ 
#include<iostream>
using namespace std;
const int MAX=3e5+10;
int a[MAX],b[MAX];
struct node{
    int l,r,w;//w记录的是这一段数据的最小值 
}tr[MAX*4];
void init(int k,int l,int r);
int requir(int k,int x);
void modify(int k,int pos,int value);
int main()
{
    int t,n;
    cin>>t;
    while(t--)
    {
        cin>>n;
        for(int i=1;i<=n;i++)cin>>a[i];
        for(int i=1;i<=n;i++)cin>>b[i];
        init(1,1,n);
        int i;
        for(i=1;i<=n;i++)
        {
            int now=requir(1,b[i]);
            if(now==-1){
                cout<<"NO"<<endl;
                break;
            }
            modify(1,now,n+1);
        }
        if(i>n)cout<<"YES"<<endl;
    }
    return 0;
}
void init(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)/2;
    init(k<<1,l,mid);
    init(k<<1|1,mid+1,r);
    tr[k].w=min(tr[k<<1].w,tr[k<<1|1].w);
}
int requir(int k,int x)
{
    if(tr[k].l==tr[k].r)
    {
        if(tr[k].w==x)return tr[k].l;
        else return -1;
    }
    if(tr[k<<1].w<=x)return requir(k<<1,x);
    else return requir(k<<1|1,x);
}
void modify(int k,int pos,int value)
{
    int l=tr[k].l;
    int r=tr[k].r;
    if(l==r&&r==pos)
    {
        tr[k].w=value;
        return;
    }
    int mid=(l+r)/2;
    if(mid>=pos)modify(k<<1,pos,value);
    else modify(k<<1|1,pos,value);
    tr[k].w=min(tr[k<<1].w,tr[k<<1|1].w);
}

 

posted @ 2019-07-25 11:52  小小笼包包  Views(78)  Comments(0)    收藏  举报