• Codeforces Round #645 (Div. 2) D、The Best Vacation


    题目链接:The Best Vacation

    题意:

    给你n个月份,每一个月份有di天。你可以呆在那里x天(x天要连续),如果你在某月的第y天呆在这。那么你的拥抱值就加y

    1<=n<=2e5

    1<=di<=1e6

    题解:

    首先这段日期的结尾一定是月末。下面证明

    如果x<=max(d1,d2...dn)

    那么肯定是在那个max(d1,d2...dn)那个月最后x天呆在那得到的拥抱值最大

    如果选取的这段日期至少覆盖到两个月份。如果右端点不是月末的话,假设左端点对应的日期大于右端点对应的日期,那么整体往左移动区间就能使得答案增加;同理假设左端点对应的日期小于右端点对应的日期可以整体往右移动。最后都会使得右端点靠到某个月的月末。

    代码:

    #include<stdio.h>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<queue>
    #include<deque>
    #include<string.h>
    #include<map>
    #include <iostream>
    #include <math.h>
    #define Mem(a,b) memset(a,b,sizeof(a))
    const double II = acos(-1);
    const double PP = (II*1.0)/(180.00);
    using namespace std;
    typedef long long ll;
    const int INF=0x3f3f3f3f;
    const double eps=1e-6;
    const double PI=acos(-1);
    const int mod=998244353;
    const int maxn=2e5+10;
    long long d[400005];
    long long sum[400005];
    long long ssum[400005];
    long long ans=0;
    long long n,x;//xһ��Ҫ��long long ��Ϊ��d�ĺ�
    int check(long long mid,long long k)
    {
        if(sum[k]-sum[mid]>=x) return 0;
        else
        {
            if(sum[k]-sum[mid-1]>=x) return 1;
            else return 2;
        }
    }
    int main()
    {
        cin>>n>>x;
        int i;
        for(i=1;i<=n;i++)
        {
            scanf("%lld",&d[i]);
            d[i+n]=d[i];
        }
        for(i=1;i<=2*n;i++)
        {
            sum[i]=sum[i-1]+d[i];
            ssum[i]=ssum[i-1]+(1+d[i])*d[i]/2;
        }
        for(i=n+1;i<=2*n;i++)
        {
            long long l=1,r=i,mid,pos;
            while(1)
            {
                mid=(l+r)/2;
                int judge=check(mid,i);
                if(judge==2) r=mid;
                else if(judge==0) l=mid+1;
                else
                {
                    pos=mid;
                    break;
                }
            }
            if(pos==i)//��ͬһ����
            {
                ans=max(ans,x*d[i]-(long long)x*(x-1)/2*1);
            }
            else
            {
                long long temp=ssum[i]-ssum[pos];
                long long xx=x-(sum[i]-sum[pos]);
                temp+=xx*d[pos]-xx*(xx-1)/2;
                ans=max(ans,temp);
            }
    
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    Dom元素的属性-卓有成效的使用
    我们90后的爱情
    Spring MVC 注解自学笔记(四) @Value
    Spring MVC学习笔记(三) @Resource
    Spring MVC学习笔记(二) 视图解析器 web请求六个阶段
    IntelliJ IDEA集成开发环境IDE自学之路
    Spring MVC注解学习笔记(一)
    持之以恒 技术是个漫长路
    JavaSE-note1-随机访问类RandomAccessFile
    [转]WINDOWS下VIM配置
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/13361942.html
Copyright © 2020-2023  润新知