Codeforces Round #111 (Div. 2) E. Buses and People 线段树|多维限制|离散化
一看发现要求满足3个条件,有点头大
可以先把所有的bus和people拎出来,用bus的s和people的l去排序,这样能保证对于当前的people,si都合法。
然后考虑如何满足ti最小的情况下,使得fi>=bj,且ti>=rj
思想有点像dp,dp里解决二维问题,一问是拿下标做状态,然后搞偏序或者LIS什么的
联想到这里也可以拿ti做下标,那么只要把ti的范围限制在[rj,max],在这个区间上找最小的fi>=bj
就变成一个经典的线段树递归问题,如果左区间满足,直接去左区间;否则去找右区间(这样能保证ti最小)
ps.有笨蛋数组开小了导致超时了,是谁我不说:)记得加区间max剪枝保证复杂度。
#include<bits/stdc++.h> #define ls (rt<<1) #define rs (rt<<1|1) #define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0) using namespace std; const int maxn=2e5+5; int ans[maxn],lisan[maxn<<1]; struct seg{ int l,r,mx,at; // }t[maxn<<2]; struct Bus{ int s,f,t; }bus[maxn]; struct Peo{ int l,r,b; }p[maxn]; void push_up(int rt){ t[rt].mx=max(t[ls].mx,t[rs].mx); } void build(int rt,int l,int r){ t[rt].l=l;t[rt].r=r; if(l==r){ t[rt].mx=0; t[rt].at=0; return; } int mid=(l+r)>>1; build(ls,l,mid);build(rs,mid+1,r); } void update(int rt,int l,int r,int val,int id){ //cout<<rt<<" "<<t[rt].l<<" "<<t[rt].r<<" "<<val<<endl; if(l<=t[rt].l&&t[rt].r<=r){ // update if(t[rt].mx<val){ t[rt].mx=val; t[rt].at=id; } //cout<<"finish"<<t[rt].mx<<" "<<t[rt].at<<endl; return; } if(t[ls].r>=l) update(ls,l,r,val,id); if(t[rs].l<=r) update(rs,l,r,val,id); push_up(rt); } int ask(int rt,int l,int r,int x){ if(l<=t[rt].l&&t[rt].r<=r){ if(t[rt].mx<x) return 0; } if(t[rt].l==t[rt].r){ if(t[rt].mx>=x) return t[rt].at; else return 0;// } int ans=0; if(t[ls].r>=l&&t[ls].mx>=x) ans=ask(ls,l,r,x);// if(ans) return ans; if(t[rs].l<=r&&t[rt].mx>=x) ans=ask(rs,l,r,x);// return ans; } int n,m; struct lys{ int pos,type; }; // find the smallest ti that fi>=ri && ti>=bi int main(){ //freopen("lys.in","r",stdin); fastio; cin>>n>>m; vector<lys>s; for(int i=1;i<=n;i++){ cin>>bus[i].s>>bus[i].f>>bus[i].t; s.emplace_back((lys){bus[i].s,i}); lisan[i]=bus[i].t; } for(int i=1;i<=m;i++){ cin>>p[i].l>>p[i].r>>p[i].b; s.emplace_back((lys){p[i].l,n+i}); lisan[i+n]=p[i].b; } sort(lisan+1,lisan+n+m+1); int len=unique(lisan+1,lisan+n+m+1)-(lisan+1); build(1,1,len); sort(s.begin(), s.end(), [&](const lys &lhs, const lys& rhs) { if(lhs.pos == rhs.pos) return lhs.type < rhs.type; return lhs.pos < rhs.pos; }); for(auto it:s){ int fir=it.pos,se=it.type; //cout<<fir<<" "<<se<<endl; if(se<=n){// bus int pos=lower_bound(lisan+1,lisan+1+len,bus[se].t)-lisan; update(1,pos,pos,bus[se].f,se); } else { se-=n;//people int pos=lower_bound(lisan+1,lisan+1+len,p[se].b)-lisan; ans[se]=ask(1,pos,len,p[se].r); if(!ans[se]) ans[se]=-1; } } for(int i=1;i<=m;i++) cout<<ans[i]<<" "; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)