Codeforces Round #826 (Div. 3) F
阿新 • • 發佈:2022-11-29
F. Multi-Colored Segments
洛谷最優解
顯然我們對於每一個線段可以分成左右兩端考慮
我們先按照l sort一遍
然後每次計算與他最近的值
我們維護兩個最大的r即可
然後每次更新
然後我們再倒著做一遍
對於每一個r 找到最近的l
然後每次更新l
我們l要記錄次大和最大 因為顏色只有相同和不同兩種
最後輸出答案的時候取min即可
其實這裡的證明並不明朗
本來我是想反著的時候還應該sort一遍的
但是比不sort更錯了
我就直接交了個不sort的 居然過了 還跑的飛快
void solve(){ int n;cin>>n; vector<tuple<int,int,int,int>>v; for(int i=1;i<=n;i++){ int l,r,c;cin>>l>>r>>c; v.push_back({l,r,c,i-1}); } sort(all(v)); int r1=-INF+1,c1=n+1,r2=-INF,c2=n+2;//r1最近 r2次近 vector<int>a(n),b(n); for(int i=0;i<n;i++){ auto [l,r,c,pos]=v[i]; if(c1!=c){ a[pos]=l-r1; }else{ a[pos]=l-r2; } //gengxin if(c==c1||c==c2){ if(c==c1){ r1=max(r1,r); }else{ r2=max(r2,r); } if(r2>r1){ swap(r1,r2); swap(c1,c2); } }else{ if(r>r2){ r2=r; c2=c; } if(r2>r1){ swap(r1,r2); swap(c1,c2); } } } int l1=INF,l2=INF+1; c1=n+1,c2=n+2; //sort(all(v),cmp); for(int i=n-1;i>=0;i--){ auto [l,r,c,pos]=v[i]; if(c1!=c){ b[pos]=l1-r; }else{ b[pos]=l2-r; } if(c==c1||c==c2){ if(c==c1){ l1=min(l1,l); }else{ l2=min(l2,l); } if(l2<l1){ swap(l1,l2); swap(c1,c2); } }else{ if(l<l2){ l2=l; c2=c; } if(l2<l1){ swap(l1,l2); swap(c1,c2); } } } for(int i=0;i<n;i++)cout<<max(0ll,min(a[i],b[i]))<<' ';cout<<endl; }