Report CodeForces - 631C (单调栈)

题目链接

题目大意:给定序列, 给定若干操作, 每次操作将$[1,r]$元素升序或降序排列, 求操作完序列

首先可以发现对最后结果有影响的序列$r$一定非增, 并且是升序降序交替的

可以用单调栈维护这些序列, 再考虑最后如何通过这些序列恢复数组

因为序列是升降交替的, 保存一个排序好的序列, 每次从两端取出元素添加即可

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#define REP(i,a,n) for(int i=a;i<=n;++i)
#define x first
#define y second
using namespace std;

typedef pair<int,int> pii;
const int N = 4e5+10;
int n, m;
int a[N], b[N];
vector<pii> s;

int main() {
    scanf("%d%d", &n, &m);
    REP(i,1,n) scanf("%d", a+i);
    REP(i,1,m) {
        int op, pos;
        scanf("%d%d", &op, &pos);
        while (!s.empty()&&pos>=s.back().y) s.pop_back();
        if (s.empty()||op!=s.back().x) s.push_back(pii(op,pos));
    }
    int L=1, R=s[0].y;
    if (s[0].x==1) sort(a+1,a+1+R);
    else sort(a+1,a+1+R,greater<int>()); 
    REP(i,1,R) b[i]=a[i];
    int now = R;
    s.push_back(pii(0,0));
    REP(i,0,s.size()-2) {
        REP(j,1,s[i].y-s[i+1].y) {
            a[now--]=(i&1?b[L++]:b[R--]);
        }
    }
    REP(i,1,n) printf("%d%c", a[i]," \n"[i==n]);
}

猜你喜欢

转载自www.cnblogs.com/uid001/p/10242144.html