Subarray Sorting【codeforces1187D】

Educational Codeforces Round 67 (Rated for Div. 2)链接


D. Subarray Sorting

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given an array ?1,?2,…,??a1,a2,…,an and an array ?1,?2,…,??b1,b2,…,bn.

For one operation you can sort in non-decreasing order any subarray ?[?…?]a[l…r] of the array ?a.

For example, if ?=[4,2,2,1,3,1]a=[4,2,2,1,3,1] and you choose subbarray ?[2…5]a[2…5], then the array turns into [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 by applying this operation any number of times (possibly zero) to the array ?a.

Input

The first line contains one integer ?t (1≤?≤3⋅1051≤t≤3⋅105) — the number of queries.

The first line of each query contains one integer ?n (1≤?≤3⋅1051≤n≤3⋅105).

The second line of each query contains ?n integers ?1,?2,…,??a1,a2,…,an (1≤??≤?1≤ai≤n).

The third line of each query contains ?n integers ?1,?2,…,??b1,b2,…,bn (1≤??≤?1≤bi≤n).

It is guaranteed that ∑?≤3⋅105∑n≤3⋅105 over 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.

 

  这道题的题意是让我们求,我们对几次这样的[l, r]的区间按生序排序,然后问,第一段区间经过这样的变化是否可以变成第二段区间?

我们用样例来举例说明:

7
1 7 1 4 4 5 6
1 1 4 4 5 7 6
这组数据,想从第一排变成第二排的,我们是不是可以把「1 7 1 4 4 5」排个序就可以了?然后就是最终的答案了。

    那么怎么去解释这样的数据呢?首先看第二排的数据的第一个“1”出现在第一排的第一位上,是可以直接不动的,那么就用掉它了;然后,往下,第二个“1”在位置三上,前面没有比它小的数,又可以用掉了(1、7换位了);然后是“4”,第一次出现“4”实在位置四上面,前面也没有比它小的数了,也是可以的,直接去与7换位即可;再往后是第二个数,在第一排中对应的第五位置是可以找到的;然后是“5”,在它的前面也是没有比它小的数了,也可以这样做到;……我们一次类推,发现整个数据都是可以推完的。

    那么,再看一组“NO”的数据:

3
1 2 3
3 2 1

  第一个是“3”,对应的第一排中,前面有“1”和“2”,那么我没没发换“3”,若取“3”就一定会取“1”,我们根据这样的关系,有了线段树维护前缀(1~qr)的最小值,并且不断更新的操作。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define MP(a, b) make_pair(a, b)
#define MP3(a, b, c) MP(MP(a, b), c)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 3e5 + 7;
int N, a[maxN], b[maxN], num[maxN], tree[maxN<<2];
inline void pushup(int rt) { tree[rt] = min(tree[lsn], tree[rsn]); }
inline void buildTree(int rt, int l, int r)
{
    if(l == r)
    {
        tree[rt] = a[l];
        return;
    }
    int mid = HalF;
    buildTree(Lson);
    buildTree(Rson);
    pushup(rt);
}
int query(int rt, int l, int r, int ql, int qr)
{
    if(ql <= l && qr >= r) return tree[rt];
    int mid = HalF;
    if(qr <= mid) return query(QL);
    else if(ql > mid) return query(QR);
    else return min(query(QL), query(QR));
}
inline void update(int rt, int l, int r, int qx)
{
    if(l == r) { tree[rt] = INF; return; }
    int mid = HalF;
    if(qx <= mid) update(Lson, qx);
    else update(Rson, qx);
    pushup(rt);
}
queue<int> vt[maxN];
inline void init()
{
    for(int i=1; i<=N; i++) num[i] = 0;
    for(int i=1; i<=N; i++) { while(!vt[i].empty()) vt[i].pop(); }
}
int main()
{
    int T; scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &N);
        init();
        for(int i=1; i<=N; i++) { scanf("%d", &a[i]); num[a[i]]++; }
        for(int i=1; i<=N; i++) { scanf("%d", &b[i]); num[b[i]]--; }
        bool flag = true;
        for(int i=1; i<=N; i++)
        {
            if(num[i] != 0)
            {
                printf("NO\n");
                flag = false;
                break;
            }
        }
        if(!flag) continue;
        buildTree(1, 1, N);
        for(int i=1; i<=N; i++) vt[a[i]].push(i);
        for(int i=1, tmp; i<=N; i++)
        {
            tmp = query(1, 1, N, 1, vt[b[i]].front());
            if(tmp < b[i]) { flag = false; break; }
            update(1, 1, N, vt[b[i]].front());
            vt[b[i]].pop();
        }
        printf(flag ? "YES\n" : "NO\n");
    }
    return 0;
}
/*
1
8
1 3 2 6 5 4 7 4
1 2 3 5 6 4 4 7
ans:YES
*/

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wuliwuliii

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值