CF1859D 题解

shinzanmono

2023-08-14 16:07:53

Solution

# CF1859D 题解 读题后发现,对于每一条线段,$(b,r]$ 只能跳回 $b$,做的是负贡献,$[l,b]$ 可以向前跳,这其实我们把所有 $[l,b]$ 合并起来,然后每次查找 $x$ 所在的线段的右端点,这就变成了一道板题了。 当然,如果 $x$ 不属于任何线段,他最多可以停在自己,所以要特判一下。 ```cpp #include<iostream> #include<algorithm> #include<set> const int sz=2e5+10; struct segment{ int l,r; bool operator<(const segment &a)const{ return l<a.l; } }line[sz]; int main(){ std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int t; std::cin>>t; while(t--){ int n,q; std::cin>>n; for(int i=1;i<=n;i++){ int l,r,a,b; std::cin>>l>>r>>a>>b; line[i]=segment{l,b}; } std::sort(line+1,line+n+1); std::set<segment>cur; cur.insert(segment{0,0}); for(int i=1;i<=n;i++){ int l=line[i].l,r=line[i].r; while(i<n&&line[i+1].l>=l&&line[i+1].l<=r)i++,r=std::max(r,line[i].r); cur.insert(segment{l,r}); } std::cin>>q; for(int i=1,x;i<=q;i++){ std::cin>>x; auto it=--cur.upper_bound(segment{x,x}); if(x<=it->r)std::cout<<it->r<<" "; else std::cout<<x<<" "; } std::cout<<"\n"; } return 0; } ```