199. Beautiful People
time limit per test: 0.25 sec.
memory limit per test: 65536 KB
memory limit per test: 65536 KB
input: standard
output: standard
output: standard
The most prestigious sports club in one city has exactly N members. Each of its members is strong and beautiful. More precisely, i-th member of this club (members being numbered by the time they entered the club) has strength S
i and beauty B
i . Since this is a very prestigious club, its members are very rich and therefore extraordinary people, so they often extremely hate each other. Strictly speaking, i-th member of the club Mr X hates j-th member of the club Mr Y if S
i ≤ S
j and B
i ≥ B
j or if S
i ≥ S
j and B
i ≤ B
j (if both properties of Mr X are greater then corresponding properties of Mr Y, he doesn't even notice him, on the other hand, if both of his properties are less, he respects Mr Y very much).
To celebrate a new 2003 year, the administration of the club is planning to organize a party. However they are afraid that if two people who hate each other would simultaneouly attend the party, after a drink or two they would start a fight. So no two people who hate each other should be invited. On the other hand, to keep the club presti≥ at the apropriate level, administration wants to invite as many people as possible.
Being the only one among administration who is not afraid of touching a computer, you are to write a program which would find out whom to invite to the party.
To celebrate a new 2003 year, the administration of the club is planning to organize a party. However they are afraid that if two people who hate each other would simultaneouly attend the party, after a drink or two they would start a fight. So no two people who hate each other should be invited. On the other hand, to keep the club presti≥ at the apropriate level, administration wants to invite as many people as possible.
Being the only one among administration who is not afraid of touching a computer, you are to write a program which would find out whom to invite to the party.
Input
The first line of the input file contains integer N — the number of members of the club. ( 2 ≤ N ≤ 100,000 ). Next N lines contain two numbers each — S i and B i respectively ( 1 ≤ S i, B i ≤ 10 9 ).
Output
On the first line of the output file print the maximum number of the people that can be invited to the party. On the second line output N integers — numbers of members to be invited in arbitrary order. If several solutions exist, output any one.
Sample test(s)
Input
4 1 1 1 2 2 1 2 2
Output
2
1 4
大致题意:
从俱乐部中选一些人参加派对。每个人都有两个属性。S和B。一些属性高低难以分辨的人之间容易互相嫉妒,不适合一起参加派对。而派对想要邀请俱乐部中尽可能多的人,而每两人之间都需要满足s1<s2 和 b1<b2 才不会互相嫉妒。
问最多能邀请到多少不会互相嫉妒的人,并且输出这些人的编号。
分析:
相当于选中的这些人的两个属性排起来都构成最长上升序列。
那么我们可以先按一个属性从小到大排序好,然后按另一个属性去找其最长上升序列。
因为数据比较大,用LIS的O(n^2)算法一定会超时,所以采用O(nlogn)算法来找LIS,并记录每个元素的前一个,方便输出。
LIS的O(nlogn)算法可以参考
http://www.slyar.com/blog/longest-ordered-subsequence.html~~~
#include
#include
#include
using namespace std;
int fa[100010],stk[100010],ret;
struct node{
int a,b,id;
}men[100010];//记录每个人的s(a)和b信息,并且记录下是第几个人。
bool cmp(node x,node y)//排序先按a升序,若相同 再按b排序。
{
if(x.a==y.a)
{
return x.b>y.b;
}
else
return x.a
men[stk[ret]].b)//比前一个元素大的数就将其选进序列
{
stk[++ret]=i;
fa[i]=stk[ret-1];//为记录lis中这个元素的前一个是哪个,为了最后输出选择了哪些人。
}
else//二分检索现选择的最长上升子列中比这个元素大的第一个数,并将其替换。
{
int begin,end;
begin=1;
end=ret;
while(begin<=end)
{
int mid=(begin+end)/2;
if(men[i].b>men[stk[mid]].b)
{
begin=mid+1;
}
else
end=mid-1;
}
stk[begin]=i;//替换,并记录其前一个人。
fa[i]=stk[begin-1];
}
}
printf("%d\n",ret);
print(stk[ret]);//递归输出选中参加party的人。
}
return 0;
}