Report CodeForces

来源:互联网 发布:应用特征数据库升级 编辑:程序博客网 时间:2024/06/03 13:36

点击打开链接

题目要求每次都对前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;}

原创粉丝点击