zoukankan      html  css  js  c++  java
  • [CF1187D] Subarray Sorting

    [CF1187D] Subarray Sorting - 线段树

    Description

    给定长度为 (n) 的数组 (a)(b)。你每次可以选择一段区间 ([l,r]),令 (a_lsim a_r) 的元素从小到大排序。你可以进行任意次操作。问能否使 (a)(b) 完全相等(对应位置上的元素相等)。

    Solution

    从左到右扫描每个 (b_i),在 (a) 中找到未被使用的最靠左的,如果它左边未被使用的数中没有比它小的,就用它,否则就无解

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    int n;
    const int N = 1e6 + 5;
    int a[N], b[N];
    
    struct SegmentTree
    {
        vector<int> a;
    
        SegmentTree(int n)
        {
            a.resize(4 * n + 4);
        }
    
        void pushup(int p)
        {
            a[p] = min(a[p * 2], a[p * 2 + 1]);
        }
    
        void build(int p, int l, int r, int *src)
        {
            if (l == r)
                a[p] = src[l];
            else
                build(p * 2, l, (l + r) / 2, src), build(p * 2 + 1, (l + r) / 2 + 1, r, src), pushup(p);
        }
    
        void modify(int p, int l, int r, int pos, int val)
        {
            if (l == r)
                a[p] = val;
            else
            {
                if (pos <= (l + r) / 2)
                    modify(p * 2, l, (l + r) / 2, pos, val);
                else
                    modify(p * 2 + 1, (l + r) / 2 + 1, r, pos, val);
                pushup(p);
            }
        }
    
        int query(int p, int l, int r, int ql, int qr)
        {
            if (l > qr || r < ql)
                return 1e9;
            if (l >= ql && r <= qr)
                return a[p];
            return min(query(p * 2, l, (l + r) / 2, ql, qr), query(p * 2 + 1, (l + r) / 2 + 1, r, ql, qr));
        }
    };
    
    void solve()
    {
        cin >> n;
        for (int i = 1; i <= n; i++)
            cin >> a[i];
        for (int i = 1; i <= n; i++)
            cin >> b[i];
        SegmentTree seg(n);
        seg.build(1, 1, n, a);
        vector<vector<int>> occur(n + 2);
        for (int i = n; i >= 1; i--)
            occur[a[i]].push_back(i);
        for (int i = 1; i <= n; i++)
        {
            int x = b[i];
            if (occur[x].size() == 0)
            {
                cout << "NO" << endl;
                return;
            }
            int p = occur[x].back();
            occur[x].pop_back();
            int qu = seg.query(1, 1, n, 1, p);
            if (qu != x)
            {
                cout << "NO" << endl;
                return;
            }
            seg.modify(1, 1, n, p, 1e9);
        }
        cout << "YES" << endl;
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        int t;
        cin >> t;
        while (t--)
            solve();
    }
    
  • 相关阅读:
    [设计模式]<<设计模式之禅>>关于迪米特法则
    [设计模式]<<设计模式之禅>>关于接口隔离原则
    [设计模式]<<设计模式之禅>>关于依赖倒置原则
    /proc/meminfo分析(一)
    Dynamic DMA mapping Guide
    Linux时钟
    Linux系统休眠和设备中断处理
    Linux调度器
    Linux调度器
    Linux标识进程
  • 原文地址:https://www.cnblogs.com/mollnn/p/14654447.html
Copyright © 2011-2022 走看看