codeforces 645 div2——D

題目

很明顯我們要令到擁抱數最大,我們儘可能讓假期在月尾開始且在月尾結束,天數不夠我們儘可能讓假期在月尾結束(代碼好寫),這個貪心是正確的是因爲我們讓假期在月尾結束,往前x天,也能保證假期儘量晚的開始,所以能保證取到的天數最大。所以大體思路是枚舉我們在哪一個月結束,二分找我們要從哪裏開始休假,然後取最大值就好了,具體實現看代碼。

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<stack>
#include<utility>
#define int long long
using namespace std;
int n,x;
int d[500000],sum1[500000],sum2[500000],ans=-1; 
signed main()
{
	cin>>n>>x;
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&d[i]);
		d[i+n]=d[i];
	}
	int n2=n*2;
	for(int i=1;i<=n2;i++)//這是個前綴和,方便處理數據
	{
		sum1[i]=sum1[i-1]+d[i];//這是月份天數的前綴和
		sum2[i]=sum2[i-1]+((1+d[i])*d[i]/2);//這個是可以獲取到的擁抱的前綴和
	}
	for(int i=n+1;i<=n2;i++)//找開始的月份
	{
		int l=1,r=i;
		while(l<r)
		{
			int mid=l+r>>1;
			if(sum1[i]-sum1[mid]<x)
			{
				r=mid;
			}
			else
			{
				l=mid+1;
			}
		}
		int k=sum1[i]-sum1[l-1]-x;
		ans=max(ans,sum2[i]-sum2[l-1]-((1+k)*k/2));//如果x天不足以支撐用完一個月份,我們就把開始天數減掉,這個可以保證我們儘量晚的開始
	}
	cout<<ans;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章