Educational Codeforces Round 67 D. Subarray Sorting

Posted heyuhhh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Educational Codeforces Round 67 D. Subarray Sorting相关的知识,希望对你有一定的参考价值。

Educational Codeforces Round 67 D. Subarray Sorting

传送门

题意;

给出两个数组\(a,b\),现在可以对\(a\)数组进行任意次排序,问最后能否得到\(b\)数组。
\(n\leq 3*10^5,a\leq n.\)

思路:

首先注意到任意次排序可以等价于任意次交换两个相邻的数,当且仅当前一个数不小于后面一个数。
我一开始想的是按权值从小到大来构造,但最终发现这条路走不通。
正解就是比较直接的思路,按位置一个一个来匹配。
对于一个\(b_i\),询问目前出现位置最早的\(a_j\),满足\(a_j=b_i\),当其能够移动过去,只要前面的数权值都不小于\(a_j\)即可。
因为我们匹配过后就要把\(a_j\)删去并且重新更新,所以不会出现\(j<i\)的情况。
以上权值线段树维护最小位置+vector存储位置即可解决。
代码如下:

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 3e5 + 5;
int T;
int n;
int a[N], b[N];
vector <int> p[N];
int Min[N << 2];
void build(int o, int l, int r) 
    Min[o] = INF;
    if(l == r) return ;
    int mid = (l + r) >> 1;
    build(o << 1, l, mid);
    build(o << 1|1, mid + 1, r);

void update(int o, int l, int r, int p, int v) 
    if(l == r) 
        Min[o] = v;
        return ;
    
    int mid = (l + r) >> 1;
    if(p <= mid) update(o << 1, l, mid, p, v);
    else update(o << 1|1, mid + 1, r, p, v);
    Min[o] = min(Min[o << 1], Min[o << 1|1]);

int query(int o, int l, int r, int L, int R) 
    if(l >= L && r <= R) return Min[o];
    int ans = INF;
    int mid = (l + r) >> 1;
    if(L <= mid) ans = min(ans, query(o << 1, l, mid, L, R));
    if(R > mid) ans = min(ans, query(o << 1|1, mid + 1, r, L, R));
    return ans;

int main() 
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> T;
    while(T--) 
        cin >> n;
        for(int i = 1; i <= n; i++) p[i].clear();
        for(int i = 1; i <= n; i++) 
            cin >> a[i];
            p[a[i]].push_back(i);
        
        for(int i = 1; i <= n; i++) cin >> b[i];
        build(1, 1, n);
        for(int i = 1; i <= n; i++) if(!p[i].empty()) 
            reverse(p[i].begin(), p[i].end());
            update(1, 1, n, i, p[i].back());
        
        bool ok = true;
        for(int i = 1; i <= n; i++) 
            if(p[b[i]].empty()) 
                ok = false;
                break;
            
            if(query(1, 1, n, 1, b[i]) < p[b[i]].back()) 
                ok = false;
                break;
            
            p[b[i]].pop_back();
            update(1, 1, n, b[i], (p[b[i]].empty() ? INF : p[b[i]].back()));
        
        if(ok) cout << "YES" << '\n';
        else cout << "NO" << '\n';
    
    return 0;

以上是关于Educational Codeforces Round 67 D. Subarray Sorting的主要内容,如果未能解决你的问题,请参考以下文章

Educational Codeforces Round 7 A

Educational Codeforces Round 7

Educational Codeforces Round 90

Educational Codeforces Round 33

Codeforces Educational Codeforces Round 54 题解

Educational Codeforces Round 27