[SGU 199] Beautiful People

[SGU 199] Beautiful People

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. 

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 irespectively ( 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


1 1 
1 2 
2 1 
2 2 

Output


1 4 

 

作为经典比赛中的一道题,想必这一定是重点的重点,那就写博记录一下.

题解:

本题虽有两个奇怪的不等式,事实上就是求最长上升子序列(读者可以想想为什么)

于是,先对两个序列排序,排序规则是第二关键字从大到小,第一关键字从小到大

然后我们就有了一个正常做lis的序列

但是因为要nlogn内完成,所以还需要二分或者树状数组优化,那么我这里只讲二分的方法,另一种留给读者去思考

首先你必须得会二分求lis,不然学习一下这个http://blog.csdn.net/wall_f/article/details/8295812

那么接下来就方便了,你只需要此时二分出第二关键字比a[i]小的最大的答案,如果他比最大的还大,那么把它加到二分序列中

同时记录下这一位是由哪一个数推过来的,即是最后所要的答案

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<algorithm>
 4 using namespace std;
 5 int n,ans=0,pre[100010],s[100010];
 6 struct xint{int x,y,num;}a[100010];
 7 bool cmp(xint x,xint y){return x.x==y.x?x.y<y.y:x.x<y.x;}
 8 int main(){
 9     scanf("%d",&n);
10     for (int i=1;i<=n;++i) scanf("%d%d",&a[i].x,&a[i].y),a[i].num=i;
11     sort(a+1,a+n+1,cmp);
12     for (int i=1;i<=n;++i){
13         int l=0,r=ans;
14         while (l<r){ 
15             int mid=l+(r-l+1)/2;
16             if (a[s[mid]].y>=a[i].y) r=mid-1; else l=mid; 
17         }
18         int res=l+1; pre[i]=s[res-1]; 
19         if (a[i].y<a[s[res]].y||s[res]==0) s[res]=i;
20         ans=max(ans,res);
21     }
22     printf("%d\n",ans);
23     for (int i=s[ans];i;i=pre[i]) printf("%d ",a[i].num);
24 }
View Code

 

posted @ 2017-10-16 18:17  logiccc  阅读(263)  评论(0编辑  收藏  举报