[BZOJ2457][BeiJing2011]双端队列 (单调性)

正如lyd所说,和数据结构本身没什么太大关联

题意

中文题面

  Sherry现在碰到了一个棘手的问题,有N个整数需要排序。
       Sherry手头能用的工具就是若干个双端队列。
      
她需要依次处理这N个数,对于每个数,Sherry能做以下两件事:
1.新建一个双端队列,并将当前数作为这个队列中的唯一的数;
2.将当前数放入已有的队列的头之前或者尾之后。
 
对所有的数处理完成之后,Sherry将这些队列排序后就可以得到一个非降的序列。
 
求Sherry最少需要的双端队列数。

思路

反方向思考

先排序好,原来的位置跟着排序

要满足双端队列,需要满足排序之后的原位置要先递减,再递增

不满足的话开新的双端队列

代码

 
#include<cstdio>
#include<algorithm>
#include<vector>
#define N 200005
#define INF 0x3fffffff
using namespace std;
int n;
pair<int, int>a[N];
vector<int>p[N];
int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i].first);
        a[i].second = i;
    }
    sort(a + 1, a + 1 + n);
    int t = 0;
    for (int i = 1; i <= n; i++)
    {
        p[++t].push_back(a[i].second);
        while (a[i].first == a[i + 1].first) p[t].push_back(a[++i].second);
    }
    for (int i = 1; i <= t; i++) sort(p[i].begin(), p[i].end());
    bool flag = 0;
    int num = INF, ans = 1;
    for (int i = 1; i <= t; i++)
    {
        int s = p[i].size();
        if (flag) {
            if (num < p[i][0]) num = p[i][s - 1];
            else {
                ++ans;
                flag = 0;
                num = p[i][0];
            }
        }
        else {
            if (num > p[i][s - 1]) num = p[i][0];
            else {
                flag = 1;
                num = p[i][s - 1];
            }
        }
    }
    printf("%d\n", ans);
    return 0;
}

 

posted @ 2018-12-22 19:06  lincold  阅读(277)  评论(0编辑  收藏  举报