题目链接:点击打开链接
题目大意:
有n辆巴士,m个人,巴士有自己的出发站 结束站 和出发时间 每个乘客也有自己的出发站 结束站 出发时间 。最后让你输出每个乘客会做哪一辆车完成它的目标,注意乘客只允许通过一辆车一次性完成目标。
这里关于多个车如果同时能完成目标的话,应该是默认坐第一辆可以完成目标的车,题目好像没有明说。
解题思路:
首先我们把所有的车和人放在一起全部排序,
排序第一关键字:左端点
排序第二关键字:id
我们首先将所有的数据输入进行排序,按照排序后的顺序依次进行操作,如果当前是车,就将这辆车的信息按照出发时间更新入线段树中(题目保证出发时间不同),我们线段树只需保存右端点即可,因为是按照左端点排序的,当我们碰到要查询乘客坐哪辆车的时候,只有线段树中已经存的结点才是有可能符合要求的,就直接对线段树内的结点进行查询即可,这也就是第二关键字的含义,要保证车排在人的面前。接着排完序之后的顺序,如果我们当前的是人的话,那就在当前的线段树中查询一个符合要求的结点即可。
以下代码:
#include<bits/stdc++.h>
#define lson rt<<1
#define rson rt<<1|1
#define pb push_back
using namespace std;
typedef long long ll;
const int INF=1e9+7;
const int N=1e5+7;
const int MOD=1e9+7;
int ans[N];
vector<int> v;
int getid(int x){ return lower_bound(v.begin(),v.end(),x)-v.begin()+1; }
struct tree //线段树结点 存右端点和车的编号
{
int l,r,mid;
int rx;
int idx;
}t[N<<3];
struct node //保存车和乘客的信息
{
int l,r,t;
int id;
bool operator<(const node &p) const
{
if(l==p.l)
return id<p.id;
return l<p.l;
}
}g[N<<1];
void pushup(int rt)
{
t[rt].rx=max(t[lson].rx,t[rson].rx);
}
void build(int l,int r,int rt)
{
int m=(l+r)>>1;
t[rt].l=l,t[rt].r=r;
t[rt].mid=m;
if(l==r)
{
t[rt].rx=-INF;
return ;
}
build(l,m,lson);
build(m+1,r,rson);
pushup(rt);
}
void update(int pos,int id,int flag,int rt) //单点更新线段树
{
if(t[rt].l==t[rt].r)
{
t[rt].rx=flag;
t[rt].idx=id;
return ;
}
if(pos<=t[rt].mid)
update(pos,id,flag,lson);
if(pos>t[rt].mid)
update(pos,id,flag,rson);
pushup(rt);
}
int query(int p,int flag,int rt) //注意这里的查询要尽可能的保证选靠左的满足要求的车
{
if(t[rt].rx<flag)
return -1;
if(t[rt].l==t[rt].r)
return t[rt].idx;
int ans=-1;
if(p<=t[rt].mid) //如果左儿子有解的话就返回左儿子的解
{
ans=query(p,flag,lson);
if(ans>0)
return ans;
}
return query(p,flag,rson); //否则查询右儿子
}
int n,m;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n+m;i++)
{
scanf("%d%d%d",&g[i].l,&g[i].r,&g[i].t);
g[i].id=i;
v.pb(g[i].t);
}
sort(v.begin(),v.end()); //排序去重
v.erase(unique(v.begin(),v.end()),v.end());
build(1,(int)v.size(),1);
sort(g+1,g+1+m+n);
for(int i=1;i<=n+m;i++)
{
int pos=getid(g[i].t);
if(g[i].id<=n) //车
update(pos,g[i].id,g[i].r,1);
else //人
ans[g[i].id-n]=query(pos,g[i].r,1);
}
for(int i=1;i<=m;i++)
{
printf("%d",ans[i]);
if(i!=m)
printf(" ");
}
printf("\n");
}