• [CF160E](Buses and People)


    题意:

    有n辆公交车,每辆公交车有s(起始点),f(终点),t(发车时间) (行驶不需要时间)

    有m个人,每个人有l(起点),r(终点),t(出现时间)

    每个人出现后会选择最早经过他且可行的公交车

    (即满足s<=l,r<=f,且公交车发车时间晚于人出现时间)

    输出每个人会选择那一辆公交车

    solution:
    将人和车一起sort

    按左端点从左到右

    且人要在车后面

    于是就可以不考虑左端点

    限制条件还剩下时间,右端点

    考虑以时间为元素建线段树并维护右端点的最大值

    当然时间点要离散

    code:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<map>
    #include<vector>
    #define ls (now<<1)
    #define rs (now<<1|1)
    #define mid ((l+r)/2)
    #define N 4008000
    #define M 200005
    #define inf 1000000007
    using namespace std;
    vector<int>v;
    int find(int x){return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}
    struct zero{
        int rx,id;//rx:该节点l到r区间内的右端点最大值,id:该最大值所代表的车次
    }tree[N];
    struct sett{
        int l,r,t;
        int id;
        bool operator<(const sett &p)const{
            if(l==p.l)return id<p.id;
            return l<p.l;
            }
    }lib[M<<1];
    int Ans[M];
    int n,m;
    void push_up(int now){
        tree[now].rx=max(tree[ls].rx,tree[rs].rx);
        }
    void build(int now,int l,int r){if(l==r){
            tree[now].rx=-inf;
            return;
        }
        build(ls,l,mid);
        build(rs,mid+1,r);
        push_up(now);
       }
    void update(int now,int l,int r,int pos,int kl,int pl){//单点修改
        if(l==r){
            tree[now].rx=kl,tree[now].id=pl;
            return;
        }
        if(mid<pos)update(rs,mid+1,r,pos,kl,pl);
        else update(ls,l,mid,pos,kl,pl);
        push_up(now);
        }
    int query(int now,int l,int r,int pos,int kl){
       if(tree[now].rx<kl)return -1;//now下没有可行的车次
       if(l==r)return tree[now].id;
       int ans=-1;
       if(pos<=mid){
           ans=query(ls,l,mid,pos,kl);
           if(ans>0)return ans;//能往左走就往左走(使时间最小)
            }
       return query(rs,mid+1,r,pos,kl);
       }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n+m;i++){
            scanf("%d%d%d",&lib[i].l,&lib[i].r,&lib[i].t);
            lib[i].id=i;
            v.push_back(lib[i].t);
            }
        sort(v.begin(),v.end());
        v.erase(unique(v.begin(),v.end()),v.end());//离散
        build(1,1,v.size());
        sort(lib+1,lib+n+m+1);
        for(int i=1;i<=n+m;i++){ 
    int plk=find(lib[i].t); if(lib[i].id<=n)update(1,1,v.size(),plk,lib[i].r,lib[i].id); else Ans[lib[i].id-n]=query(1,1,v.size(),plk,lib[i].r); } for(int i=1;i<=m;i++)printf("%d ",Ans[i]); }
  • 相关阅读:
    从书上学的东西(顺带总结一发)
    网上讲的好的知识点汇总
    土地征用题解(兼斜率优化详解)
    Blocks题解(区间dp)
    高精度模板汇总
    动态规划总结
    异或序列(题解)(莫队)
    小Z的袜子(题解)(莫队)
    小B的询问(题解)(莫队)
    凸包模板——Graham扫描法
  • 原文地址:https://www.cnblogs.com/stepsys/p/10374758.html
Copyright © 2020-2023  润新知