codeforce 631C Report

原题地址:http://codeforces.com/problemset/problem/631/C

 

题意

给定一个序列,先后依次进行m次操作,每一次都会把区间[1-r]内的数升序或者降序排列,求m次操作之后的序列

 

题解

很明显,对于某一段区间的数字,和对他们最后的操作有关

用Time[]数组记录对应位置操作的时间。

用opr[]数组记录对应位置操作的选择

首先,考虑两个操作,区间分别为[1,r1],[1,r2],时间为t1,t2,升降序分别为opr1,opr2;且t1>t2,opr1!=opr2;

如果r1>r2,那么2的操作的影响完全被覆盖,没有意义;

如果r1<r2,那么(r1,r2]这个区间受到opr2的影响,之后的区间则由opr1决定。

 

那么具体的对应关系是怎样的呢?

我们不妨假设r最大的区间要求升序,那么初始时整个数组升序,用双指针s,t分别指向0和r+1。

假如某个操作要求降序,那么受到该操作影响的部分应该是剩余序列的若干最小值,++s,对应地,如果某个操纵要求升序,则--t;

 

这道题s,t如何初始化,如何操作,值得讨论

 

#include<bits/stdc++.h>

#define clr(x,y) memset((x),(y),sizeof(x))

using namespace std;
typedef long long LL;

const int maxn=2e5;

int A[maxn+5];
int Time[maxn+5];
int opr[maxn+5];
int ans[maxn+5];

int s,t,p,d,start;

void Copy(int x)
{
    if (x==opr[start])
    {
        for (int j=1;j<=d;++j)
        {
            --t;
            --p;
            ans[p]=A[t];
        }
    }
    else
    {
        for (int j=1;j<=d;++j)
        {
            ++s;
            --p;
            ans[p]=A[s];
        }
    }
    d=0;
}

int main(void)
{
    #ifdef ex
    freopen ("../in.txt","r",stdin);
    //freopen ("../out.txt","w",stdout);
    #endif

    int n,m;
    scanf("%d%d",&n,&m);

    for (int i=1;i<=n;++i)
    {
        scanf("%d",&A[i]);
    }

    clr(Time,0);
    clr(opr,0);
    int tt,tr;
    for (int i=1;i<=m;++i)
    {
        scanf("%d%d",&tr,&tt);
        Time[tt]=i;
        opr[tt]=tr;
    }

    for (int i=n;i>=1;--i)
    {
        if (Time[i])
        {
            start=i;
            break;
        }
        ans[i]=A[i];
    }

    if (opr[start]==1) sort(A+1,A+start+1);
    else sort(A+1,A+start+1,greater<int>() );

    //ans[start]=A[start];

    s=0;
    t=start+1;
    int now_time=0;
    int now_opr=3;

    d=0;
    p=start+1;
    Time[0]=m+1;
    for (int i=start;i>=0;--i)
    {
        if (Time[i]>now_time)
        {
            Copy(now_opr);
            now_opr=opr[i];
            now_time=Time[i];
        }
        ++d;
    }

    for (int i=1;i<=n;++i)
        printf("%d ",ans[i]);
}

 

 

 

 

 

 

转载于:https://www.cnblogs.com/123-123/p/5568743.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值