• 题解 CF160E 【Buses and People】


    题意:

    给定n辆公交车 (t_i)时间从(s_i)出发去(f_i),

    有m个人,(b_i)时间或之后从(l_i)(r_i)

    求每个人最早搭哪辆车。

    即:对于每个人 求公交车(t_i)最小,且(t_ige b_i),(l_ige s_i),(f_ile r_i)

    分析:

    离散化时间。按照(l_i)排序,再按照公交->人 排序

    按时间建立线段树。

    按照排好序的将车插入线段树,线段树维护(f_i)的最大值。

    查询时,查询([1,b_i])区间中满足(f_ile r_i)的最小(t_i)

    (按照顺序插入,保证了(l_ige s_i))

    再次体会到线段树的强大。

    @jljljl 太强了 我看ta题解懂的。代码可能会相似。

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,x,y) for(int i=x;i<=y;i++)
    #define per(i,x,y) for(int i=x;i>=y;i--)
    #define rd(x) scanf("%d",&x)
    typedef long long LL;
    const int N=1e5+10,inf=0x3f3f3f3f;
    int n,m,lsh[N<<1],ans[N],tr[N<<3]; 
    struct pos{
    	int t,l,r,tp,id;
    }tmp[N<<1];
    bool cmp(pos x,pos y){ return (x.l==y.l)?(x.tp>y.tp):(x.l<y.l); }
    void pushup(int rt){ tr[rt]=(tmp[tr[rt<<1]].r>tmp[tr[rt<<1|1]].r)?tr[rt<<1]:tr[rt<<1|1]; }
    void update(int rt,int l,int r,int x,int id){
    	if(l==r){
    		if(tmp[tr[rt]].r<tmp[id].r) tr[rt]=id; //维护最大r(以序号形式) 
    		return;
    	}
    	int mid=l+r>>1;
    	if(x<=mid) update(rt<<1,l,mid,x,id);
    	else update(rt<<1|1,mid+1,r,x,id);
    	pushup(rt);
    }
    int query(int rt,int l,int r,int x,int id){
    	if(tmp[tr[rt]].r<tmp[id].r||lsh[r]<tmp[id].t) return -1;
    	//公交车的最大r还不如查询r 或者公交车的t小于查询t
    	if(l==r) return tmp[tr[rt]].id;
    	int mid=l+r>>1;
    	int ret=query(rt<<1,l,mid,x,id);
    	if(ret!=-1) return ret; 
    	ret=query(rt<<1|1,mid+1,r,x,id);
    	return ret;
    }
    int main(){
    	rd(n);rd(m);
    	rep(i,1,n){
    		rd(tmp[i].l),rd(tmp[i].r),rd(tmp[i].t);
    		tmp[i].tp=1,tmp[i].id=i;
    		lsh[i]=tmp[i].t;
    	}
    	rep(i,1,m){
    		rd(tmp[i+n].l),rd(tmp[i+n].r),rd(tmp[i+n].t);
    		tmp[i+n].tp=0,tmp[i+n].id=i;
    		lsh[i+n]=tmp[i+n].t;
    	}
    	
    	sort(lsh+1,lsh+n+m+1);sort(tmp+1,tmp+n+m+1,cmp);
    	int tot=unique(lsh+1,lsh+n+m+1)-lsh-1;
    	
    	for(int i=1;i<=n+m;i++){
    		int nwt=lower_bound(lsh+1,lsh+tot+1,tmp[i].t)-lsh;
    		if(tmp[i].tp) update(1,1,tot,nwt,i);
    		else ans[tmp[i].id]=query(1,1,tot,nwt,i);
    	}
    	rep(i,1,m) printf("%d ",ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    在windows桌面显示IP等信息的小工具分享
    oracle,根据查询结果结构创建新表
    Oracle多表关联如何更新多个字段
    我想实现一个通用的配置读写类
    【转】Android程序右上角不显示3个点的菜单
    python发送 IBM lotus Notes 邮件
    当超过端口MTU时
    为什么telnet可以用来检查TCP端口是否正常?
    55+手绘网站设计 – 构建极具创新效果的网站
    炫酷动态静图40例——多图杀猫
  • 原文地址:https://www.cnblogs.com/zdsrs060330/p/13912605.html
Copyright © 2020-2023  润新知