码迷,mamicode.com
首页 > 其他好文 > 详细

ATcoder

时间:2019-11-08 14:02:57      阅读:179      评论:0      收藏:0      [点我收藏+]

标签:nbsp   col   cin   因此   article   https   win   using   str   

题目连接: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

标签:nbsp   col   cin   因此   article   https   win   using   str   

原文地址:https://www.cnblogs.com/Accepting/p/11819726.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!