SGU 199 Beautiful People lis O(nlogn)算法

来源:互联网 发布:js里面加载js 编辑:程序博客网 时间:2024/05/29 15:42

点击打开链接题目链接

199. Beautiful People

time limit per test: 0.25 sec.
memory limit per test: 65536 KB
input: 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 Si and beauty Bi . 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 Si ≤ Sj and Bi ≥ Bj or if Si ≥ Sj and Bi ≤ Bj (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 — Si and Bi respectively ( 1 ≤ Si, Bi ≤ 109 ). 

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


1 4 

数据有点大

需要用到O(nlogn)的算法

二分= = 

这题的状态需要注意一下

因为需要输出路径

所以不能单纯记录那个值 

而是应该记录这个值的位置

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXN=100100;int id[MAXN],pre[MAXN];struct Node{    int a,b,id;}node[100100];int n;int cmp(Node x,Node y){    if(x.a!=y.a)        return x.a<y.a;    return x.b>y.b;}void print(int x){    if(x==-1)        return ;    print(pre[x]);    printf("%d ",node[x].id);}int main(){    int i,left,right,mid;    int len;    while(scanf("%d",&n)!=EOF)    {        for(i=1;i<=n;i++)        {            scanf("%d %d",&node[i].a,&node[i].b);            node[i].id=i;        }        sort(node+1,node+1+n,cmp);        //for(i=1;i<=n;i++)          //  printf("%d %d %d\n",node[i].a,node[i].b,node[i].id);        len=1;        memset(pre,-1,sizeof(pre));        id[0]=1;        for(i=2;i<=n;i++)        {            if(node[i].b>node[id[len-1]].b)            {                id[len++]=i;                pre[i]=id[len-2];                continue;            }            left=0;            right=len-1;            while(left<right)            {                mid=(left+right)/2;                if(node[id[mid]].b<node[i].b)                {                    left=mid+1;                }                else                {                    right=mid;                }            }            id[left]=i;            if(left==0)                pre[i]=-1;            else            pre[i]=id[left-1];        }        printf("%d\n",len);        print(id[len-1]);        puts("");    }    return 0;}


0 0