码迷,mamicode.com
首页 > 其他好文 > 详细

ZOJ 3963 Heap Partition(multiset + stl自带二分 + 贪心)题解

时间:2018-11-08 00:13:46      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:ack   math   printf   \n   com   迭代器   父节点   ==   nbsp   

题意:给你n个数字s1~sn,要你把它们组成一棵棵二叉树,对这棵二叉树来说,所有节点来自S,并且父节点si<=子节点sj,并且i<j,问你树最少几棵二叉数、树

思路:贪心。我们往multiset加还能加子节点的节点,二分查找一个个大于等于当前插入节点的节点,然后插入,若找不到则重新建一棵树。

没想到set自带lower_bound(),第一次迭代器遍历TLE就想着手动写二分...然后发现自带二分...

代码:

#include<iostream>
#include<stdio.h>
#include<cmath>
#include<string>
#include<queue>
#include<set>
#include<vector>
#include<string.h>
#include<algorithm>
typedef long long int ll;
using namespace std;
const int maxn = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
vector<int> G[maxn];
struct node{
    int id, sz, num;
};
struct compare{
    bool operator () (node a, node b){
        return a.sz > b.sz;
    }
};
node add(int id, int sz){
    node a;
    a.id = id , a.sz = sz, a.num = 0;
    return a;
}
multiset<node, compare> q;
int main(){
    int T, a;
    scanf("%d", &T);
    while(T--){
        q.clear();
        int n;
        scanf("%d", &n);
        scanf("%d", &a);
        int cnt = 2;
        q.insert(add(1, a));
        G[1].clear();
        G[1].push_back(1);
        node p;
        for(int i = 2; i <= n; i++){
            scanf("%d" ,&a);
            multiset<node>::iterator it;
            p.sz = a;
            it = q.lower_bound(p);
            if(it == q.end()){
                q.insert(add(cnt, a));
                G[cnt].clear();
                G[cnt].push_back(i);
                cnt++;
            }
            else{
                p = *it;
                q.erase(it);
                p.num++;
                if(p.num < 2)
                    q.insert(p);
                q.insert(add(p.id, a));
                G[p.id].push_back(i);
            }
        }
        printf("%d\n", cnt - 1);
        for(int i = 1; i < cnt; i++){
            int len = G[i].size();
            printf("%d", len);
            for(int j = 0; j < len; j++)
                printf(" %d", G[i][j]);
            printf("\n");
        }
    }
    return 0;
}

 

ZOJ 3963 Heap Partition(multiset + stl自带二分 + 贪心)题解

标签:ack   math   printf   \n   com   迭代器   父节点   ==   nbsp   

原文地址:https://www.cnblogs.com/KirinSB/p/9926387.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!