题意给你一个序列,让你将这些序列分成子序列,这些子序列都必须是堆序。
思路贪心选取,每次加入一个数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();
}
}
}