Codeforces#344 Div2 C問題

はじめに

Codeforces Round #344 Div. 2 Prob. C. Report

問題:http://codeforces.com/contest/631/problem/C

数列が与えられる。先頭からr番目の要素までを、降順または昇順でソートするクエリが順番に与えられる。最後の状態を出力。

考え方

クエリをrでソートして、後ろから確定するかんじ。確定されていない要素の中でのmaxかminの要素が後ろから並んでいく。確定されていない要素はmultisetで管理した。計算量はO(nlogn+mlogm)。

解法

#include <algorithm>
#include <iostream>
#include <set>
#include <vector>
using namespace std;

class Query{
public:
    int pos;
    bool is_nondes;
    int t;
    bool operator <(const Query& q2){
        return (pos!=q2.pos)? pos<q2.pos : t < q2.t;
    };
};

int main() {
    cin.tie(nullptr); ios::sync_with_stdio(false);

    int n,m;
    cin >> n >> m;

    vector<int> a(n);
    multiset<int> items;
    for(int i = 0; i < n; ++i){
        cin >> a[i];
        items.insert(a[i]);
    }

    cout << endl;
    vector<Query> queries(m);
    for(int i = 0; i < m; ++i){
        int t,r;
        bool is_nondes = false;
        cin >> t >> r;
        --r;
        if(t==1) is_nondes = true;
        queries[i].pos = r;
        queries[i].is_nondes = is_nondes;
        queries[i].t = i;

    }

    sort(queries.rbegin(), queries.rend());

    vector<int> ans(a);
    int last_pos = n;
    int last_t = -1;
    bool last_is_nondes = true;
    for(int i = 0; i < m; ++i){
        int pos = queries[i].pos;
        bool is_nondes = queries[i].is_nondes;
        int t = queries[i].t;
        if(last_t == -1){
            for(int j = last_pos-1; pos < j; --j){
                int item = a[j];
                ans[j] = item; items.erase(items.find(item));
            }
            last_pos = pos;
            last_t = t;
            last_is_nondes = is_nondes;
        }else if(last_pos!=pos&&last_t<t){
            for(int j = last_pos; pos < j; --j){
                if(last_is_nondes){
                    int item = *items.rbegin();
                    ans[j] = item; items.erase(items.find(item));
                }else{
                    int item = *items.begin();
                    ans[j] = item; items.erase(items.find(item));
                }
            }
            last_pos = pos;
            last_t = t;
            last_is_nondes = is_nondes;
        }

    }

    for(int j = last_pos; 0 <= j; --j){
        if(last_is_nondes){
            int item = *items.rbegin();
            ans[j] = item; items.erase(items.find(item));
        }else{
            int item = *items.begin();
            ans[j] = item; items.erase(items.find(item));
        }
    }
    for(int i = 0; i < n; ++i){
        if(i!=0) cout << " ";
        cout << ans[i];
    }
    cout << endl;
    return 0;
}