-
题意:一年有\(n\)个月,每月有\(d_{i}\)天,找出连续的\(x\)天,使得这\(x\)天的日期总和最大,任意一年都能选.
-
题解:首先要先贪心,得到:连续的\(x\)天的最后一天一定是某个月的最后一天,我们先预处理两个前缀和,分别记录连续的天数和总日期数,然后枚举,二分找出一个区间,得出这个区间的总日期数再加上区间最左边的剩余的\(x\)的总日期,每次维护一个最大值即可.(记得开\(long\ long\))
-
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <stack> #include <queue> #include <vector> #include <map> #include <set> #include <unordered_set> #include <unordered_map> #define ll long long #define fi first #define se second #define pb push_back #define me memset const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; ll n,x; ll a[N]; ll pre1[N],pre2[N]; int main() { ios::sync_with_stdio(false);cin.tie(0); cin>>n>>x; for(int i=1;i<=n;++i){ cin>>a[i]; a[n+i]=a[i]; } n*=2; for(int i=1;i<=n;++i){ pre1[i]=pre1[i-1]+a[i]; pre2[i]=pre2[i-1]+a[i]*(a[i]+1)/2; } ll ans=0; for(int i=1;i<=n;++i){ if(pre1[i]>=x){ int pos=lower_bound(pre1+1,pre1+1+n,pre1[i]-x)-pre1; ll rest=x-(pre1[i]-pre1[pos]); ll res=(pre2[i]-pre2[pos])+(a[pos]+a[pos]-rest+1)*rest/2; ans=max(ans,res); } } printf("%lld\n",ans); return 0; }