先按x排序,对于相同的x分块处理,也就是x相同的一起处理。dp[i]=dp[j]+1,由于x相同是一起处理所以只要a[i]>a[j]即可。
建议先看一下本博客里的LIS线段树优化的文章。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
struct pi{
int x;
int y;
int id;
}pp[100005];
int a[100005];
int dp[100005];
int b[100005];
int cmp(pi a,pi b){
if(a.x!=b.x) return a.x<b.x;
return a.y<b.y;
}
int get(int x,int y,int n){
int le,ri,mid;
le=1;
ri=n;
while(le<=ri){
mid=(le+ri)/2;
if(pp[b[mid]].y<y&&pp[b[mid]].x<x) le=mid+1;
else ri=mid-1;
}
return le;
}
struct ppi{
int le;
int ri;
int max;
int m;
}pp1[400005];
void build(int tot,int l,int r){
pp1[tot].le=l;
pp1[tot].ri=r;
pp1[tot].max=0;
pp1[tot].m=-1;
if(l==r) return ;
build(2*tot,l,(l+r)/2);
build(2*tot+1,(l+r)/2+1,r);
}
void merg(int tot,int p,int m,int id){
if(pp1[tot].le==pp1[tot].ri){
if(pp1[tot].max<m){
pp1[tot].max=m;
pp1[tot].m=id;
}
return ;
}
int mid;
mid=(pp1[tot].le+pp1[tot].ri)/2;
if(p<=mid){
merg(2*tot,p,m,id);
}
else{
merg(2*tot+1,p,m,id);
}
if(pp1[2*tot].max<pp1[2*tot+1].max){
pp1[tot].max=pp1[2*tot+1].max;
pp1[tot].m=pp1[2*tot+1].m;
}
else{
pp1[tot].max=pp1[2*tot].max;
pp1[tot].m=pp1[2*tot].m;
}
}
int query(int tot,int n){
if(pp1[tot].le>=1&&pp1[tot].ri<=n){
return pp1[tot].m;
}
int x,y;
int mid;
mid=(pp1[tot].le+pp1[tot].ri)/2;
x=-1;
y=-1;
x=query(2*tot,n);
if(n>mid){
y=query(2*tot+1,n);
}
if(x==-1) return y;
if(y==-1) return x;
if(dp[x]<dp[y]) return y;
return x;
}
int main()
{
int i,n,m,k,p,tot,j,f;
while(cin>>n){
tot=0;
for(i=1;i<=n;i++){
scanf("%d%d",&pp[i].x,&pp[i].y);
pp[i].id=i;
b[++tot]=pp[i].y;
}
sort(pp+1,pp+1+n,cmp);
sort(b+1,b+tot+1);
m=tot;
build(1,1,m);
for(i=1;i<=n;i++){
p=i;
while(p<n&&pp[p].x==pp[p+1].x) p++;
for(j=i;j<=p;j++){
if(i==1){
dp[j]=1;
a[j]=-1;
}
else{
k=lower_bound(b+1,b+1+m,pp[j].y)-b;
if(k==1){
dp[j]=1;
a[j]=-1;
}
else{
f=query(1,k-1);
if(f==-1){
dp[j]=1;
a[j]=-1;
continue;
}
a[j]=f;
dp[j]=dp[f]+1;
}
}
}
for(j=i;j<=p;j++){
k=lower_bound(b+1, b+1+m, pp[j].y)-b;
merg(1,k,dp[j],j);
}
i=p;
}
p=0;
for(i=1;i<=n;i++){
p=max(p,dp[i]);
}
for(i=1;i<=n;i++){
if(dp[i]==p){
printf("%d\n",p);
printf("%d",pp[i].id);
k=a[i];
while(k!=-1){
printf(" %d",pp[k].id);
k=a[k];
}
printf("\n");
break;
}
}
}
}