zoukankan      html  css  js  c++  java
  • 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]);
    }

     

     

     

     

     

  • 相关阅读:
    递归
    高等数学思维导图——1.函数与极限
    sort方法和自定义比较器的写法
    PriorityQueue(优先队列)
    常用JAVA API :HashSet 和 TreeSet
    常用Java API:HashMap 和 TreeMap
    ArrayList、Vector和LinkedList的区别
    构造方法
    面向对象特点:封装、继承、多态
    匿名对象
  • 原文地址:https://www.cnblogs.com/123-123/p/5568743.html
Copyright © 2011-2022 走看看