码迷,mamicode.com
首页 > 其他好文 > 详细

Educational Codeforces Round 67 D. Subarray Sorting

时间:2019-08-07 10:44:31      阅读:83      评论:0      收藏:0      [点我收藏+]

标签:push   出现   names   等价   就是   syn   并且   开始   一个   

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

标签:push   出现   names   等价   就是   syn   并且   开始   一个   

原文地址:https://www.cnblogs.com/heyuhhh/p/11313784.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!