zoj 3963

来源:互联网 发布:虚拟位置软件ios 编辑:程序博客网 时间:2024/06/11 00:30

题意给你一个序列,让你将这些序列分成子序列,这些子序列都必须是堆序。

思路贪心选取,每次加入一个数x,看最右边小于x的最大数y,加入y的堆序列中。然后就ok了
要用set来看,但是set的low_bound需要用set的成员函数。。。。如果不用就是t。、、、

#include <string>#include <iostream>#include <cmath>#include <map>#include <algorithm>#include <set>#include <vector>#include <cstdio>using namespace std;typedef long long LL;const int MaxN = 1e5;struct Point {    int w, num, size, pos;};bool operator<(Point a, Point b){        if (a.w == b.w) {            return a.pos > b.pos;        }        return a.w > b.w;    }set<Point>s;int a[MaxN + 5], n;vector<int>bag[MaxN + 5];int main(){    int T;    scanf("%d", &T);    while(T--) {        s.clear();        scanf("%d", &n);        int tot = 0;        for(int i = 1; i <= n; i++) {            scanf("%d", &a[i]);            Point t; t.w = a[i]; t.num = 0; t.pos = i;            set <Point> :: iterator it = s.lower_bound(t);            if(it == s.end()) {                t.size = ++tot;            }            else {                Point now = *it;                s.erase(now);                now.num++;                if(now.num == 1){                    s.insert(now);                }                t.size = now.size;            }            bag[t.size].push_back(i);            s.insert(t);        }        printf("%d\n", tot);        for(int i = 1; i <= tot; i++) {            printf("%d ", bag[i].size());            for(int j = 0; j < bag[i].size(); j++) printf("%d ", bag[i][j]);            printf("\n");        }        for(int i = 1; i <= tot; i++) {            bag[i].clear();        }    }}
0 0
原创粉丝点击