Codeforces 631C Report【其他】

来源:互联网 发布:矩阵与行列式的区别 编辑:程序博客网 时间:2024/06/03 17:33

题意:

给定序列,将前a个数进行逆序或正序排列,多次操作后,求最终得到的序列。

分析:

仔细分析可以想到j<i,且rj小于ri的操作是没有意义的,对于每个i把类似j的操作删去(这里可以用multiset或者直接模拟栈的操作),最后我们会获得一个严格下降的序列即ri>rj && i<j,并且相邻的t不相等。
那么对于riri+1,对[0,ri)进行排序后,又对其子序列[0,ri+1)进行相反的排序,其实只有区间[ri+1,ri1]]内的数是按照ti规定的排序的,并且不会再改变。所以我们只需要根据ti获取[ri+1,ri1]]之间的值即可。
那么如何获取呢?在头尾两头设两个指针,如果对应区间要求升序,则用大的数填,否则用小的数填上。

代码:

用multiset做(做题太少第一次用set的erase)

#include <cstdio>#include<set>#include<algorithm>#include<iostream>using namespace std;const int maxn = 200005;int a[maxn], b[maxn];typedef pair<int, int>p;#define fi first#define se secondmultiset<p>ms;int main (void){    int n, m;scanf("%d%d", &n, &m);    for(int i = 0; i < n; i++){        scanf("%d", &a[i]);        b[i] = a[i];    }    int maxr = 0;    int r, t;    multiset<p>::iterator pos;    multiset<p>::iterator rp;    for(int i = 0; i < m; i++){        scanf("%d%d", &t, &r);        p tp = p(r, t);        maxr = max(maxr, r);        rp = ms.begin();        while(rp ->first <= tp.first && rp!=ms.end())             ms.erase(rp++);        ms.insert(tp);    }    sort(b, b + maxr);    int u = maxr - 1, l = 0;    pos = ms.end();    pos--;    int cnt = 0;    while(cnt < ms.size()){        int tmp = pos->se;        cnt++;        if(cnt == ms.size()){            for(int j = (pos->fi) - 1; j >=0; j--){                if(tmp == 1) a[j] = b[u--];                else a[j] = b[l++];            }        }        else{            rp = pos--;            for(int j = (rp->fi) - 1; j >= pos->fi; j--){                if(tmp == 1) a[j] = b[u--];                else a[j] = b[l++];            }       }     }    for(int i = 0; i < n; i++){       printf("%d%c", a[i], i == n - 1?'\n':' ' );    }    return 0;}

模拟栈的操作

#include <cstdio>#include<algorithm>using namespace std;//区间递减且t交叉const int maxn = 200005;int a[maxn], b[maxn], t[maxn], r[maxn];int main (void){    int n, m;scanf("%d%d", &n, &m);    for(int i = 0; i < n; i++){        scanf("%d", &a[i]);        b[i] = a[i];    }    int s = 0;    for(int i = 0; i < m; i++){        scanf("%d%d", &t[i], &r[i]);        while(s > 0 && r[i] >= r[s - 1]){            s--;        }        t[s] = t[i], r[s] = r[i]; s++;    }   sort(b, b + r[0]);   int l = r[0] - 1, u = 0;    r[s] = 0;   for(int i = 1; i < s + 1; i++){    for(int j = r[i - 1] - 1; j >= r[i]; j--){        if(t[i - 1] == 2) a[j] = b[u++];        else a[j] = b[l--];        }   }   //for(int i = 0; i < n; i++) printf("%d",b[i]);   for(int i = 0; i < n; i++)        printf("%d%c", a[i], i==n-1?'\n':' ');    return 0;}

智商捉急。。。。比赛的时候就是想不到怎么保存有意义的操作, 就断定这题是一定是要用到自己没学过的数据结构。。真的要对自己自信呀~~思考思考!!

0 0
原创粉丝点击