CodeForces

来源:互联网 发布:unity 编写js文件 编辑:程序博客网 时间:2024/06/14 15:18


题目链接:点击打开链接


题目大意:

有n辆巴士,m个人,巴士有自己的出发站 结束站 和出发时间  每个乘客也有自己的出发站 结束站 出发时间 。最后让你输出每个乘客会做哪一辆车完成它的目标,注意乘客只允许通过一辆车一次性完成目标。

这里关于多个车如果同时能完成目标的话,应该是默认坐第一辆可以完成目标的车,题目好像没有明说。


解题思路:

首先我们把所有的车和人放在一起全部排序,

排序第一关键字:左端点

排序第二关键字:id


我们首先将所有的数据输入进行排序,按照排序后的顺序依次进行操作,如果当前是车,就将这辆车的信息按照出发时间更新入线段树中(题目保证出发时间不同),我们线段树只需保存右端点即可,因为是按照左端点排序的,当我们碰到要查询乘客坐哪辆车的时候,只有线段树中已经存的结点才是有可能符合要求的,就直接对线段树内的结点进行查询即可,这也就是第二关键字的含义,要保证车排在人的面前。接着排完序之后的顺序,如果我们当前的是人的话,那就在当前的线段树中查询一个符合要求的结点即可。


以下代码:

#include<bits/stdc++.h>#define lson rt<<1#define rson rt<<1|1#define pb push_backusing 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");}






原创粉丝点击