您的位置:首页 > 其它

zoj 3963 Heap Partition 贪心+upper_bound()

2017-05-03 14:31 190 查看
题目链接

题意:

构造尽可能少的一种结构,父节点的值小于等于子节点,而且子节点在序列中出现在父节点

后面。而且每个父节点至多有两个子节点。

思路:

 这个题就是贪心来做就好,对于新来的一个点,我们看看在前面能否找到比该点值小的,如果

有,就利用贪心的思想,找前面比他小的当中最大的那一个来,如果找不到的话就必须要新增加

一个堆了.另外需要注意的是,由于一个父节点最多有两个子节点,所以我们要开一个数组记录

该父节点的子节点数,当等于两个时候,就将其从set中删除.至于找到前面的当中最小的当中

最大的那个,我们这里可以用到upper_bound(),找到其前面当中大于该数的第一个数.那么往

前一个就是最小的当中最大的那个了.(注意我们找到返回的是地址)

剩下的就是一些细节就不多说了....

#include<bits/stdc++.h>
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while(a--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 100000007
#define inf 0x3f3f3f3f
#define exp 0.00000001
#define  pii  pair<int, int>
#define  mp   make_pair
#define  pb   push_back
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int num[maxn],dgree[maxn];
vector<int>vt[maxn];
struct node
{
int item;
int id;
}p;
bool operator<(node a,node b)
{
if(num[a.id]==num[b.id])
return a.id<b.id;
return num[a.id]<num[b.id];
}
set<node>st;
set<node>::iterator it;
int main()
{
int t;
int n;
Ri(t);
W(t)
{
st.clear();
Ri(n);
memset(dgree,0,4*n+4);
int cnt=0;
for(int i=1;i<=n;i++)
{

Ri(num[i]);
p.id=i;
it=st.upper_bound(p);
if(it==st.begin())
{
vt[cnt].pb(i);
p.item=cnt,p.id=i;
st.insert(p);
cnt++;
}
else
{
it--;
p=*it;
dgree[p.id]++;
if(dgree[p.id]==2)
st.erase(it);
p.id=i;
st.insert(p);
vt[p.item].pb(i);
}
}
Pi(cnt);
for(int i=0;i<cnt;i++)
{
printf("%d",vt[i].size());
for(int j=0;j<vt[i].size();j++)
{
printf(" %d",vt[i][j]);
}
puts("");
vt[i].clear();
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: