3419. 双向排序

题目链接

3419. 双向排序

给定序列 (a1,a2,,an)=(1,2,,n),即 ai=i

小蓝将对这个序列进行 m 次操作,每次可能是将 a1,a2,,aqi 降序排列,或者将 aqi,aqi+1,,an 升序排列。

请求出操作完成后的序列。

输入格式

输入的第一行包含两个整数 n,m,分别表示序列的长度和操作次数。

接下来 m 行描述对序列的操作,其中第 i 行包含两个整数 pi,qi 表示操作类型和参数。当 pi=0 时,表示将 a1,a2,,aqi 降序排列;当 pi=1 时,表示将 aqi,aqi+1,,an 升序排列。

输出格式

输出一行,包含 n 个整数,相邻的整数之间使用一个空格分隔,表示操作完成后的序列。

数据范围

对于 30% 的评测用例,n,m1000
对于 60% 的评测用例,n,m5000
对于所有评测用例,1n,m1050pi11qin

输入样例:

3 3 0 3 1 2 0 2

输出样例:

3 1 2

样例解释

原数列为 (1,2,3)

1 步后为 (3,2,1)

2 步后为 (3,1,2)

3 步后为 (3,1,2)。与第 2步操作后相同,因为前两个数已经是降序了。

解题思路

思维

首先可以肯定的一点:前缀操作和后缀操作是交替进行的,且第一步操作肯定是前缀操作,因为如果出现连续的前缀操作或者后缀操作,这些连续的操作都可以合成一个操作
另外以前缀操作为例:如果一个前缀操作可以覆盖上一个前缀操作,由于这个操作包含的元素包括了前两次的元素,所以这次前缀操作可以取代前两次操作,后缀操作也是如此

  • 时间复杂度:O(n+m)

代码

// Problem: 双向排序 // Contest: AcWing // URL: https://www.acwing.com/problem/content/3422/ // Memory Limit: 256 MB // Time Limit: 1000 ms // // Powered by CP Editor (https://cpeditor.org) // %%%Skyqwq #include <bits/stdc++.h> //#define int long long #define help {cin.tie(NULL); cout.tie(NULL);} #define pb push_back #define fi first #define se second #define mkp make_pair using namespace std; typedef long long LL; typedef pair<int, int> PII; typedef pair<LL, LL> PLL; template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; } template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; } template <typename T> void inline read(T &x) { int f = 1; x = 0; char s = getchar(); while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); } while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar(); x *= f; } const int N=1e5+5; PII stk[N]; int top,res[N]; int main() { int n,m; cin>>n>>m; while(m--) { int p,q; cin>>p>>q; if(p==0) { while(top&&stk[top].fi==0)q=max(stk[top--].se,q); while(top>=2&&stk[top-1].se<q)top-=2; stk[++top]={0,q}; } else if(top) { while(top&&stk[top].fi==1)q=min(stk[top--].se,q); while(top>=2&&stk[top-1].se>q)top-=2; stk[++top]={1,q}; } } int l=1,r=n,k=n; for(int i=1;i<=top;i++) { if(stk[i].fi==0) while(l<=r&&stk[i].se<r)res[r--]=k--; else while(l<=r&&stk[i].se>l)res[l++]=k--; if(l>r)break; } if(top&1) while(l<=r)res[l++]=k--; else while(l<=r)res[r--]=k--; for(int i=1;i<=n;i++)cout<<res[i]<<' '; return 0; }

__EOF__

本文作者acwing_zyy
本文链接https://www.cnblogs.com/zyyun/p/15917016.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   zyy2001  阅读(317)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示