0
点赞
收藏
分享

微信扫一扫

Report CodeForces - 631C


题目要求每次都对前r个数进行升序或降序排序

我们发现 第一次对前三个数升序排序 如果第二次对前五个数排序 那第二次不管是升序还是降序都会覆盖第一次的排序 也就是说第一次的排序做了无用功

据此我们可以使用单调栈 来简化所给命令

 

注意 不可以对栈中每一个命令都彻底执行 比如

5 4

1 2 3 4 5

2 4

1 3

2 2

1 1

这样就有n^2*log(n)的复杂度

要充分利用已排序的部分 每执行一条命令 只需将部分元素逆序翻转即可 这样用两个变量 l r 就可实现 详见代码

 

#include <bits/stdc++.h>
using namespace std;

struct node
{
int t;
int p;
};

stack <int> ans;
node order[200010];
node stk[200010];
int num[200010];
int n,m,top,pos;

int cmp1(int u,int v)
{
return u<v;
}

int cmp2(int u,int v)
{
return u>v;
}

void init()
{
int i,j,maxx;
stk[0].t=0,stk[0].p=0;
maxx=0,top=0;
for(i=m;i>=1;i--)
{
if(order[i].t==stk[top].t)
{
if(order[i].p>stk[top].p)
{
stk[top]=order[i];
}
}
else
{
if(order[i].p>stk[top].p)
{
top++;
stk[top]=order[i];
}
}
}
return;
}

void calculate()
{
int i,t,l,r;
while(!ans.empty()) ans.pop();
l=1,r=n;
while(r>stk[top].p)
{
ans.push(num[r]);
r--;
}
if(stk[top].t==1) sort(num+l,num+r+1,cmp1);
else sort(num+l,num+r+1,cmp2);
top--;

while(top>=1)
{
if(l<=r)
{
while(r>l+stk[top].p-1)
{
ans.push(num[r]);
r--;
}
t=l,l=r,r=t;
}
else
{
while(r<l-stk[top].p+1)
{
ans.push(num[r]);
r++;
}
t=l,l=r,r=t;
}
top--;
}
if(l<=r)
{
while(l<=r)
{
ans.push(num[r]);
r--;
}
}
else
{
while(r<=l)
{
ans.push(num[r]);
r++;
}
}

while(!ans.empty())
{
printf("%d ",ans.top());
ans.pop();
}
printf("\n");
return;
}

int main()
{
int i,j,maxx,l,r;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=1;i<=n;i++)
{
scanf("%d",&num[i]);
}
for(i=1;i<=m;i++)
{
scanf("%d%d",&order[i].t,&order[i].p);
}

init();
calculate();
}
return 0;
}

 

 

 


举报

相关推荐

0 条评论