1. 程式人生 > >Report CodeForces - 631C (單調棧)

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]); }