ZOJ - 3963 Heap Partition STL +思維

ZOJ - 3963 Heap Partition

題意:

給定一個 n 個數的序列,存在一棵二叉樹他存放的元素滿足 ai <= aj && i<j (i爲 j 的父節點),要將這 n 個數全部都存到二叉樹中(可以不在同一棵樹),求最少需要多少棵樹。

每一個案例先輸出需要多少棵樹,

每棵樹的第一行輸出一個x,代表這棵樹有幾個元素,然後輸出這x個元素在原數組中的位置

題解:

對於每一個新插入的點,找前面≤它的最大點做爲它的父親。沒有就新建一個。 一個節點可以有兩個兒子。

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<bitset>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#define mod 1000000007
#define ls rt<<1
#define rs rt<<1|1
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
struct node
{
    int v,id; //  值    下標
    int k;  //記錄屬於哪一顆樹
    node(int a,int b,int c):v(a),id(b),k(c){}
    bool operator < (node a)const
    {
        if(v==a.v)
            return id<a.id;
        return v<a.v;
    }
};
int vis[maxn];  //標記
set<node> s;
set<node>::iterator it;
vector<int> v[maxn];
int main()
{
    int t;
    int n,x;
    scanf("%d",&t);
    while(t--)
    {
        int ans = 0; //有多少棵樹
        s.clear();
        scanf("%d",&n);
        for(int i=0;i<=n;i++)
        {
            v[i].clear();
            vis[i] = 0;
        }
        scanf("%d",&x);
        s.insert(node(x,1,++ans));
        v[ans].push_back(1);
        for(int i=2;i<=n;i++)
        {
            scanf("%d",&x);
            it = s.upper_bound(node(x,i,ans));
            if(it==s.begin())   //如果 s 爲空 或者 第一個元素就比要插入的元素大(存入 s 的結構體已經從小到大排好序),就新建一個
            {
                s.insert(node(x,i,++ans));
                v[ans].push_back(i);
            }
            else
            {
                it--;
                node a = *it;
                s.insert(node(x,i,a.k));
                vis[a.id]++;
                if(vis[a.id]==2)
                    s.erase(it);
                v[a.k].push_back(i);
            }
        }
        printf("%d\n",ans);
        for(int i=1;i<=ans;i++)
        {
            int len = v[i].size();
            printf("%d",len);
            for(int j=0;j<len;j++)
                printf(" %d",v[i][j]);
            printf("\n");
        }
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章