0
点赞
收藏
分享

微信扫一扫

Subarray Sorting 思维+前缀最小值

舟海君 2022-03-19 阅读 50
算法c++

题目要求每次可以选择一个不减的区间进行排序,那么显然暴力翻转不可行,那么考虑对性质进行维护。

我们考虑从小到达对每个数字进行归位操作。对于 B [ i ] B[i] B[i]而言,如果其在 A [ ] A[] A[]中的位置为 p o s pos pos,且 B [ i ] B[i] B[i] [ 1 , p o s ] [1, pos] [1,pos]的最小值,那么才能够进行归位操作。因为之前匹配的元素实际上已经移动到了前面,但是我们并没有实际上对 A A A序列进行修改,即所有未匹配过在 [ 1 , p o s ] [1,pos] [1,pos]这一区间的值的位置都在 B [ i ] B[i] B[i]之后了。对于已经归位的值,只需要置为无穷大即可,这样可以保证不对后面的交换产生影响。

#include <bits/stdc++.h>
#define int long long
#define endl '\n'

const int N = 3e5 + 10;
int a[N], b[N];

namespace segmentTree{
    const int INF = 1e9 + 7;
    int tree[N << 2];
    
    #define lson rt << 1, l, mid
    #define rson rt << 1 | 1, mid + 1, r

    inline void push_up(int rt){ tree[rt] = std::min(tree[rt << 1], tree[rt << 1 | 1]); }

    inline void build(int rt, int l, int r){
        if(l == r){
            tree[rt] = INF;
            return;
        }
        int mid = l + r >> 1;
        build(lson), build(rson);
        push_up(rt);
    }

    inline void update(int rt, int l, int r, int pos, int val){
        if(l == r){
            tree[rt] = val;
            return;
        }
        int mid = l + r >> 1;
        if(mid >= pos) update(lson, pos, val);
        else update(rson, pos, val);
        push_up(rt);
    }

    inline int query(int rt, int l, int r, int L, int R){
        if(l >= L && r <= R) return tree[rt];
        int mid = l + r >> 1, ans = INF;
        if(mid >= L) ans = std::min(ans, query(lson, L, R));
        if(mid <  R) ans = std::min(ans, query(rson, L, R));
        return ans;
    }
}   

std::queue<int> q[N];

inline void solve(){
    int n = 0; std::cin >> n; segmentTree::build(1, 1, n);
    for(int i = 1; i <= n; i++) while(q[i].size()) q[i].pop();
    for(int i = 1; i <= n; i++) std::cin >> a[i], q[a[i]].emplace(i), segmentTree::update(1, 1, n, i, a[i]);
    for(int i = 1; i <= n; i++) std::cin >> b[i];
    for(int i = 1; i <= n; i++){
        if(!q[b[i]].size()) { std::cout << "NO" << endl; return; }
        int now = q[b[i]].front(); q[b[i]].pop();
        int t = segmentTree::query(1, 1, n, 1, now);
        if(t != b[i]) { std::cout << "NO" << endl; return; }
        segmentTree::update(1, 1, n, now, segmentTree::INF);
    }
    std::cout << "YES" << endl;
} 

signed main(){
    std::ios_base::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
    int t = 0; std::cin >> t;
    while(t--) solve();
    return 0;
}
举报

相关推荐

0 条评论