hdu 6119 二分 OR 尺取

来源:互联网 发布:mac 4k 字体太小 编辑:程序博客网 时间:2024/06/05 06:17


题目链接


题意:给你n个人区间 可能重合包含 给你m次机会每次可以填补一个点 求最大连续长度


没错我越来越菜了,因为去重多加一个分号debug两小时.


这个题就先将重复交叉的去掉合并,然后预处理每两个线段的差值为多少,然后用尺取法,或者二分(枚举起点,二分终点来确定区间) 都可以过的.   

哎...屡败屡战.


二分


#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;typedef long long ll;const int maxn = 2e5 + 5;struct node{    ll l, r;}a[maxn],q[maxn];int cmp(const node &a, const node &b){if(a.l==b.l)return a.r < b.r;return a.l<b.l;}ll sum[maxn];int main(){    int n, m;    while(~scanf("%d%d", &n, &m))    {        memset(sum, 0, sizeof(sum));        ll ans = 0;        for(int i = 1; i <= n; i++)            scanf("%lld%lld", &a[i].l, &a[i].r);             sort(a+1, a+1+n, cmp);            a[n+1].l=1e9+7;            a[n+1].r=-1;            int cnt=1;            ll w=a[1].r;int tt=1,nexr=w;            for(int i=2;i<=n+1;i++)            {            if(a[i].l-1<=w)            {            if(a[i].r>w)            w=a[i].r;}            else if(a[i].l-1>w)            {            q[cnt].l=a[tt].l;            q[cnt].r=w;            w=a[i].r;            tt=i;            cnt++;}}sum[1]=q[1].l-1;        for(int i = 2; i <cnt; i++)            sum[i] = sum[i-1] + ((q[i].l - q[i-1].r - 1 )> 0 ? (q[i].l - q[i-1].r - 1 ): 0);        for(int i=1;i<cnt;i++)        ans=max(ans,q[i].r-q[i].l+1+m);        for(int i = 1; i < cnt; i++)        {            int l = i, r = cnt-1, mid, tmp;            ll pre = 0;            while(l <= r)            {                mid = (l+r)/2;                if(sum[mid]-sum[i] <= m)                {                    tmp = mid, l = mid + 1, pre = m - (sum[mid]-sum[i]);                    ans = max(ans, q[tmp].r-q[i].l+1+pre);                }                else r = mid - 1;            }        }        printf("%lld\n", ans);    }    return 0;}/*5 10000001 2000002000 50003333 233333444 444446666 66667*/



尺取


#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;typedef long long ll;const int maxn = 2e5 + 5;struct node{    ll l, r;}a[maxn],q[maxn];int cmp(const node &a, const node &b){if(a.l==b.l)return a.r < b.r;return a.l<b.l;}int main(){    int n, m;    while(~scanf("%d%d", &n, &m))    {        ll ans = 0;        for(int i = 1; i <= n; i++)            scanf("%lld%lld", &a[i].l, &a[i].r);             sort(a+1, a+1+n, cmp);            a[n+1].l=1e9+7;            a[n+1].r=-1;            int cnt=1;            ll w=a[1].r;int tt=1,nexr=w;            for(int i=2;i<=n+1;i++)            {            if(a[i].l-1<=w)            {            if(a[i].r>w)            w=a[i].r;}            else if(a[i].l-1>w)            {            q[cnt].l=a[tt].l;            q[cnt].r=w;            w=a[i].r;            tt=i;            cnt++;}} ans=0; ll l=1,r=1,len=0;while(l<cnt){while(r+1<cnt&&len+q[r+1].l-q[r].r-1<=m){len+=q[r+1].l-q[r].r-1;r++;}ans=max(ans,q[r].r-q[l].l+1+m-len);len-=q[l+1].l-q[l].r-1;l++;}printf("%lld\n",ans);    }    return 0;}/*5 10000001 2000002000 50003333 233333444 444446666 66667*/


原创粉丝点击