ATcoder
Posted accepting
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ATcoder相关的知识,希望对你有一定的参考价值。
题目连接:https://atcoder.jp/contests/agc040/tasks/agc040_b
题意:有N个问题,每个问题可以由编号L~R之间的人完成,有两个集合S和T,将N个问题放入两个集合中,使得交集和最大
题解:https://blog.csdn.net/duanghaha/article/details/102892233
找到最大的L设为A和最小的R设为B,分两种情况,当A和B在同一个集合里时,那么该集合无论放多少元素,其交集都为R-L+1,另外一个集合我们可以选择只放一个区间长度最大的maxlen,
因此答案为 maxlen+R-L+1
第二种情况,A和B不在同一个集合中,那么对于A所在集合,交集为ans1=min(r[i]-L+1),对于B所在的集合其交集为ans2=min(R-l[i]+1);答案为ans1+ans2;
这个问题可以转化为:一个数组, 其中没个元素都包含l,,r,让我们求将这个数组中的元素放到两个集合中,使得r[i](min,集合1)+l[i](min,集合2)最大。
我们把数组按照a排序,然后维护b的后缀最小值,最后枚举ans=max(ans,s[i].a+minnr[i+1])(不太懂。。。)
ACcode
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll N=1E5+7; const ll INF =1e9+7; ll l[N],r[N]; struct stu{ ll a,b; bool friend operator < (const stu &x,const stu &y) { return x.a>y.a; } }s[N]; ll arr[N]; int main(){ ll n; cin>>n; for(ll i=1;i<=n;i++) cin>>l[i]>>r[i]; ll ans1=0; ll maxlen=0; ll minnr=INF,p; ll maxxl=0,q; for(ll i=1;i<=n;i++){ if(l[i]>maxxl) { maxxl=l[i]; p=i; } if(r[i]<minnr){ minnr=r[i]; q=i; } maxlen=max(maxlen,r[i]-l[i]+1); } ans1+=maxlen; if(minnr>maxxl) ans1+=minnr-maxxl+1; for(ll i=1;i<=n;i++){ s[i].a=max(r[i]-maxxl+1,(ll)0); s[i].b=max(minnr-l[i]+1,(ll)0); } sort(s+1,s+1+n); arr[n+1]=INF; for(ll i=n;i>=1;i--) arr[i]=min(arr[i+1],s[i].b); ll ans2=0; for(ll i=1;i<n;i++) { ans2=max(ans2,s[i].a+arr[i+1]); } cout<<max(ans2,ans1)<<endl; return 0; }
以上是关于ATcoder的主要内容,如果未能解决你的问题,请参考以下文章
AtCoder ABC 154E Almost Everywhere Zero