zoukankan      html  css  js  c++  java
  • 2017百度之星初赛(B)-1006-小小粉丝度度熊 hdu 6119

    去重合并,以某个点为起点,向后二分到最后一个满足未签到天数<=m的点。

    二分时的查询有很多方法,可以用线段树,dp,前缀数组等等。比赛时没有想到前缀数组,就用来dp来完成查询,查询一次大约O(logn)。前缀数组的话查询O(1)更快一些。

    同学说尺取法也可以。

    dp[i][j]代表第i个区间到第i+(1<<j)个区间的间隙和

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<iostream>
    #include<queue>
    #include<map>
    #include<cmath>
    #include<set>
    #include<stack>
    #define ll long long
    #define pb push_back
    #define max(x,y) ((x)>(y)?(x):(y))
    #define min(x,y) ((x)>(y)?(y):(x))
    #define cls(name,x) memset(name,x,sizeof(name))//0或-1
    #define fs first
    #define sc second
    #define mp make_pair
    #define L(x) (1<<x)
    #define next Next
    using namespace std;
    const int inf=1e9+10;
    const ll llinf=1e16+10;
    const int maxn=1e5+10;
    const int maxm=1e3+10;
    const int mod=1e9+7;
    int n,m;
    struct node
    {
        int l,r;
    }p[maxn];
    bool cmp(const node &a,const node &b)
    {
        return a.l<b.l;
    }
    int dp[maxn][20];
    void init()
    {
        for(int j=1;L(j)<=n;j++)
            for(int i=1;i+L(j)<=n;i++)
            dp[i][j]=dp[i][j-1]+dp[i+L(j-1)][j-1];
    }
    int query(int L,int R)
    {
        if(L>=R) return 0;
        int t=0;
        while(1)
        {
            if(L+L(t+1)<=R)
                t++;
            else break;
        }
        return dp[L][t]+query(L+L(t),R);
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(~scanf("%d %d",&n,&m))
        {
            for(int i=1;i<=n;i++)
                scanf("%d %d",&p[i].l,&p[i].r);
            sort(p+1,p+1+n,cmp);
            int k=1;
            for(int i=2;i<=n;i++)
            {
                if(p[i].l<=p[k].r+1&&p[i].r>p[k].r)
                    p[k].r=p[i].r;
                else if(p[i].l>p[k].r+1)
                    p[++k]=p[i];
            }
            n=k;
            /*for(int i=1;i<=k;i++)
                printf("%d %d
    ",p[i].l,p[i].r);*/
            dp[n][0]=0;
            for(int i=1;i<=n-1;i++)
                dp[i][0]=p[i+1].l-p[i].r-1;
            init();
            int ans=m;
            for(int i=1;i<=n-1;i++)
            {
                int l=i+1,r=n;
                int temp=i;
                while(l<=r)
                {
                    int mid=(l+r)/2;
                    if(query(i,mid)<=m)
                    {
                        temp=max(temp,mid);
                        l=mid+1;
                    }
                    else r=mid-1;
                }
                ans=max(ans,p[temp].r-p[i].l+1+m-query(i,temp));
            }
            ans=max(ans,p[n].r-p[n].l+1+m);
            printf("%d
    ",ans);
        }
        return 0;
    }

    sum[i]代表第i个区间之前的所有间隙和

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<iostream>
    #include<queue>
    #include<map>
    #include<cmath>
    #include<set>
    #include<stack>
    #define ll long long
    #define pb push_back
    #define max(x,y) ((x)>(y)?(x):(y))
    #define min(x,y) ((x)>(y)?(y):(x))
    #define cls(name,x) memset(name,x,sizeof(name))//0或-1
    #define fs first
    #define sc second
    #define mp make_pair
    #define L(x) (1<<x)
    #define next Next
    using namespace std;
    const int inf=1e9+10;
    const ll llinf=1e16+10;
    const int maxn=1e5+10;
    const int maxm=1e3+10;
    const int mod=1e9+7;
    int n,m;
    struct node
    {
        int l,r;
    }p[maxn];
    bool cmp(const node &a,const node &b)
    {
        return a.l<b.l;
    }
    int sum[maxn];
    int query(int L,int R)
    {
        return sum[R]-sum[L];
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(~scanf("%d %d",&n,&m))
        {
            for(int i=1;i<=n;i++)
                scanf("%d %d",&p[i].l,&p[i].r);
            sort(p+1,p+1+n,cmp);
            int k=1;
            for(int i=2;i<=n;i++)
            {
                if(p[i].l<=p[k].r+1 && p[i].r>p[k].r)
                    p[k].r=p[i].r;
                else if(p[i].l>p[k].r+1)
                    p[++k]=p[i];
            }
            n=k;
            sum[1]=0;
            for(int i=2;i<=n;i++)
                sum[i]=sum[i-1]+p[i].l-p[i-1].r-1;
            int ans=m;
            for(int i=1;i<=n-1;i++)
            {
                int l=i+1,r=n;
                int temp=i;
                while(l<=r)
                {
                    int mid=(l+r)/2;
                    if(query(i,mid)<=m)
                    {
                        temp=max(temp,mid);
                        l=mid+1;
                    }
                    else r=mid-1;
                }
                ans=max(ans,p[temp].r-p[i].l+1+m-query(i,temp));
            }
            ans=max(ans,p[n].r-p[n].l+1+m);
            printf("%d
    ",ans);
        }
        return 0;
    }

     尺取法

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<iostream>
    #include<queue>
    #include<map>
    #include<cmath>
    #include<set>
    #include<stack>
    #define ll long long
    #define pb push_back
    #define max(x,y) ((x)>(y)?(x):(y))
    #define min(x,y) ((x)>(y)?(y):(x))
    #define cls(name,x) memset(name,x,sizeof(name))//0或-1
    #define fs first
    #define sc second
    #define mp make_pair
    #define L(x) (1<<x)
    #define next Next
    using namespace std;
    const int inf=1e9+10;
    const ll llinf=1e16+10;
    const int maxn=1e5+10;
    const int maxm=1e3+10;
    const int mod=1e9+7;
    int n,m;
    struct node
    {
        int l,r;
    }p[maxn];
    bool cmp(const node &a,const node &b)
    {
        return a.l<b.l;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(~scanf("%d %d",&n,&m))
        {
            for(int i=1;i<=n;i++)
                scanf("%d %d",&p[i].l,&p[i].r);
            sort(p+1,p+1+n,cmp);
            int k=1;
            for(int i=2;i<=n;i++)
            {
                if(p[i].l<=p[k].r+1 && p[i].r>p[k].r)
                    p[k].r=p[i].r;
                else if(p[i].l>p[k].r+1)
                    p[++k]=p[i];
            }
            n=k;
            int l=1,r=1,cost=0;
            int ans=m;
            while(l<=n-1)
            {
                while(p[r+1].l-p[r].r-1 <= m-cost && r+1<=n)
                {
                    cost+=p[r+1].l-p[r].r-1;
                    r++;
                }
                ans=max(ans,p[r].r-p[l].l+1 + m-cost);
                if(l!=r)
                cost-=p[l+1].l-p[l].r-1;
                l++;
                r=max(r,l);
            }
            ans=max(ans,p[n].r-p[n].l+1 + m);
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    用户IP地址的三个属性的区别(HTTP_X_FORWARDED_FOR,HTTP_VIA,REM_addr
    Backbone源码分析-Backbone架构+流程图
    为什么我的SQL server 在附加数据库后,数据库总是变成了只读?
    js window.open()实现打印,如何在关闭打印窗口时刷新父窗口
    .NET获取不到js写的cookie解决方法
    网站安全狗”响应内容保护“网页错误返回页面优化功能介绍
    快钱支付与Sql Server的乐观锁和悲观锁
    RequiredFieldValidator 根据group组来触发验证
    DropDownList中显示无限级树形结构
    大量多风格多功能后台管理模板
  • 原文地址:https://www.cnblogs.com/mgz-/p/7354457.html
Copyright © 2011-2022 走看看