您的位置:首页 > 运维架构

SGU 199. Beautiful People(最长上升子序列nlogn LIS)

2017-10-16 18:01 288 查看

Problem Statement

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.

Example

Input

4

1 1

1 2

2 1

2 2

Output

2

1 4

题意

一个俱乐部里一共有n个人,每个人有两个值,力量S和美丽B,让你求出一组人,使得这一组人里面对于每个人i,1<i<=n,Si>Si−1 and Bi>Bi−1,并且人数要最多。简单说就是要求一个二维最长上升子序列。

思路

首先由题意得,这题要求的是二维的最长上升子序列,而根据数据范围来看,还是要nlogn的,如果两维一起做的话大概是不可行的,而两维分开做,求出的最长上升子序列又有很大可能是不一样的。所以我们有这样一种想法,对于所有人我们先排序,将S从小到大排序并将S相等的人将B从大到小排序,这样我们就可以只用对B这一维进行最长上升子序列了。因为这样排序的话,S相等的,B最大的都在最前面,后面的不会影响。还有,这题需要打印一组可行的解,我们对于每一位,记录一个pre,表示这一位的前面符合的第一个是哪一位,最后只要递归打印就可以出解了。

Code

#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline void readInt(int &x) {
x=0;int f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
x*=f;
}
inline void readLong(ll &x) {
x=0;int f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
x*=f;
}
/*================Header Template==============*/
const ll base=1e9;
ll x[100010],idx[100010];
int n,len,pre[100010];
struct peo{ll x,y;int id;}p[100010];
inline bool cmp(peo a,peo b){return a.x==b.x?a.y>b.y:a.x<b.x;}
inline void print(int ans) {
if(ans==0)
return;
print(pre[ans]);
printf("%d",p[ans].id);
putchar(x[len]==ans?'\n':' ');
}
int main() {
readInt(n);
for(int i=1;i<=n;i++) {
p[i].id=i;
readLong(p[i].x);
readLong(p[i].y);
}
sort(p+1,p+n+1,cmp);
x[1]=1;
int len=1;
for(int i=2;i<=n;i++) {
int l=1,r=len;
while(l<=r) {
int mid=(l+r)>>1;
if(p[x[mid]].y<p[i].y)
l=mid+1;
else
r=mid-1;
}
x[l]=i;
pre[i]=x[l-1];
len=max(len,l);
}
printf("%d\n",len);
print(x[len]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  sgu