zoukankan      html  css  js  c++  java
  • Codeforces E67 D. Subarray Sorting

    题目链接

    题目:

    给你两个数组a[], b[],对第一个数组你可以选择任意一个区间[l,r]进行从小到大排序。问能不能将a数组经过多次操作变成b数组。

    题解:

    首先,我们能发现一个数要向前移动,只能前面的数比它大时才可以向前移。所以要想把a变成b相当于用a中的数构造b,扫一遍b对每一位b[i],在a中
    找到第一个和b[i]相同的数a[k],要想移到b[i]位置这个a[k]要是从i到j的最小值。
    如何快速找到每个a[j]呢?我们可以开n个queue,每个队列保存a[]中数的位置。每次对b[i]取queue[b[i]]的队头,就是位置k,如果我们每次使用一个数后把它从a[]
    中删除掉,那只用判断a[k]是1~k的最小值就说明可以用a[k]构造b[i],这个可以用线段树取维护。每次删除相当于在线段树中把这一位设为INF.

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i, a, n) for(ll i = a; i <= n; ++ i)
    #define per(i, a, n) for(ll i = n; i >= a; -- i)
    typedef long long ll;
    const int N = 3e5 + 105;
    const int mod = 998244353;
    const double Pi = acos(- 1.0);
    const int INF = 0x3f3f3f3f;
    const int G = 3, Gi = 332748118;
    ll qpow(ll a, ll b) { ll res = 1; while(b){ if(b) res = (res * a) % mod; a = (a * a) % mod; b >>= 1;} return res; }
    ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
    //
    
    int T, n;
    int a[N], b[N];
    queue<int>sol[N];
    
    struct Tree{
        int l, r;
        int minval;
    }tree[N * 4];
    
    void Pushup(int index){
        tree[index].minval = min(tree[index << 1].minval, tree[index << 1 | 1].minval);
    }
    
    void Build(int l, int r, int index){
        tree[index].l = l;
        tree[index].r = r;
        tree[index].minval = INF;
        if(l == r){
            tree[index].minval = a[l];
            return;
        }
        int mid = (l + r) >> 1;
        Build(l, mid, index << 1);
        Build(mid + 1, r, index << 1 | 1);
        Pushup(index);
    }
    
    void Updata(int l,int r,int index,int val){
    	if(tree[index].l == tree[index].r){
            tree[index].minval = val;
    		return;
    	}
    	int mid = tree[index].l + tree[index].r >> 1;
    	if(l <= mid) Updata(l, r, index << 1, val);
    	if(r > mid) Updata(l, r, index << 1 | 1, val);
    	Pushup(index);
    }
    
    
    int query(int l, int r, int index){
        if(l <= tree[index].l && tree[index].r <= r){
            return tree[index].minval;
        }
        int mid = (tree[index].l + tree[index].r) >> 1;
        int res = INF;
        if(l <= mid) res = min(res, query(l, r, index << 1));
        if(r > mid) res = min(res, query(l, r, index << 1 | 1));
        return res;
    }
    
    
    int main()
    {
        scanf("%d",&T);
        while(T --){
            scanf("%d",&n);
            for(int i = 1; i <= n; ++ i){
                while(sol[i].size()) sol[i].pop();
            }
            for(int i = 1; i <= n; ++ i){
                scanf("%d",&a[i]);
                sol[a[i]].push(i);
            }
            Build(1, n, 1);
            int flag = 0, k;
            for(int i = 1; i <= n; ++ i){
                int x; scanf("%d",&x);
                if(flag) continue;
                if(sol[x].size()){
                    k = sol[x].front(); sol[x].pop();
                    int tt = query(1, k, 1);
                    if(tt == x)  Updata(k, k, 1, INF);
                    else flag = 1;
                }
                else flag = 1;
            }
            if(flag) printf("NO
    ");
            else printf("YES
    ");
        }
        return 0;
    }
    
    
    
  • 相关阅读:
    springboot新手脱坑之无法下载依赖包
    07_mybatis延迟加载
    05_mybatis动态sql
    04_Mybatis输入出映射
    C#-----类FileStream的使用
    JavaWeb-----JSP详解
    JavaWeb-----ServletConfig对象和servletContext对象
    JavaWeb-----实现第一个Servlet程序
    JavaScript--浅谈!=、!==、==和===的区别
    EasyUI学习-----表格DataGrid格式化formatter用法
  • 原文地址:https://www.cnblogs.com/A-sc/p/13500760.html
Copyright © 2011-2022 走看看