分析:找所有比(a,b)小的数,可以先以找第一个数a比小的所有集合中,第二个数比b小的集合,肯定不能两次sort,可以用线段树+set来搞定这件事情,线段树的坐标为a的值,每个节点存的东西为一个set集合,所有第一个数比a小的集合,然后要找第二个数比b小的集合,只需要在set里面找就好了,这个时候时间复杂度:o(nlognlogn),第一次以为这样会MLE,事实上是不会的,因为算每个集合最多属于多少个set容器,最多属于logn个set容器。因此总的空间复杂度为:o(nlogn)
注意使用set的判重函数方式,,
friend bool operator<(node x,node y)
{
if(x.b!=y.b)
return x.b<y.b;
else
return x.id<y.id;
}
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<set>
#include<queue>
#include<cstring>
#include<stack>
using namespace std;
int a[500005];
int cnt;
struct node
{
int a,b,c,d;
int id;
friend bool operator<(node x,node y)
{
if(x.b!=y.b)
return x.b<y.b;
else
return x.id<y.id;
}
}it[100005];
int vis[100005];
int pre[100005];
int dis[100005];
const int inf=100000000;
int lb(int x)
{
return x&(-x);
}
set<node>s[400005];
queue<int>q;
void add(int x,int id)
{
while(x<=400002)
{
s[x].insert(it[id]);
x+=lb(x);
}
}
int n;
void get(int x,int y,int dist,int pid)
{
while(x>=1)
{
set<node>::iterator itm;
itm=s[x].begin();
while(itm!=s[x].end()&&(itm->b)<=y)
{
int tid=itm->id;
if(vis[tid]==1)
{
s[x].erase(itm++);
}
else
{
vis[tid]=1;
dis[tid]=dist+1;
pre[tid]=pid;
q.push(tid);
s[x].erase(itm++);
}
}
x-=lb(x);
}
}
void bfs()
{
int x=0,y=0;
while(!q.empty())
q.pop();
int tx=lower_bound(a,a+cnt,x)-a;
get(tx+1,y,0,-1);
if(it[n-1].a==0&&it[n-1].b==0){
dis[n-1]=1;
return ;
}
while(!q.empty())
{
int tid=q.front();
q.pop();
if(it[tid].c<=x&&it[tid].d<=y)
continue;
if(it[tid].c>=it[n-1].a&&it[tid].d>=it[n-1].b)
{
dis[n-1]=dis[tid]+1;
pre[n-1]=tid;
return ;
}
x=it[tid].c;
y=it[tid].d;
tx=lower_bound(a,a+cnt,x)-a;
get(tx+1,y,dis[tid],tid);
}
return;
}
int main()
{
while(~scanf("%d",&n))
{
cnt=0;
for(int i=0;i<=400002;i++)
s[i].clear();
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++)
{
pre[i]=-1;
dis[i]=inf;
scanf("%d%d%d%d",&it[i].a,&it[i].b,&it[i].c,&it[i].d);
it[i].id=i;
a[cnt++]=it[i].a;
a[cnt++]=it[i].b;
a[cnt++]=it[i].c;
a[cnt++]=it[i].d;
}
a[cnt++]=0;
sort(a,a+cnt);
cnt=unique(a,a+cnt)-a;
for(int i=0;i<n;i++)
{
int tx=lower_bound(a,a+cnt,it[i].a)-a;
add(tx+1,i); //attention
}
bfs();
if(dis[n-1]==inf)
{
printf("-1\n");
}
else
{
printf("%d\n",dis[n-1]);
stack<int> ans;
int tp=n-1;
while(tp!=-1)
{
ans.push(tp);
tp=pre[tp];
}
while(!ans.empty())
{
printf("%d ",ans.top()+1);
ans.pop();
}
printf("\n");
}
}
}