zoukankan      html  css  js  c++  java
  • CF 1358D The Best Vacation

    https://codeforces.com/contest/1358/problem/D

    题目

    某地一年有$n$个月,第$i$个月有$d_i$天,每个月的第$j$天可以被拥抱$j$次,你需要选择连续的x天,问你最多能被拥抱多少次,$x<sum d_i$

    $1 leqslant n leqslant 2 cdot 10^5$,$1 leqslant d_i leqslant 10^6$

    题解

    非常难受的一道题,最后10分钟才证出来,CF上的证明是反证……

    如果把前i天的被抱次数列出来,得到$a_i$

    [1,quad2,quad3,cdots,quad d_1,1quad 2, cdots, d_n]

    然后考虑前n项和$S_n$,问题是求最大的$S_n-S_{n-x}$

    变形一下

    [sum_n (a_n-a_{n-x})]

    然后画一个图

    发现极大值只可能在一个月的最后一天取得

    最后枚举最后一天,然后计算就可以了

    还要注意x会爆int

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define MAXN 400007
    int d[MAXN];//, b[MAXN];
    long long s[MAXN], ss[MAXN];
    int n;
    long long x;
    long long calc(long long i) {
    	int ii=lower_bound(s+1,s+n+n+1,i)-s-1;
    	long long ri=i-s[ii];
    	return ss[ii]+(ri+1ll)*ri/2;
    }
    int main() {
    	scanf("%d%lld", &n, &x);
    	d[0]=0;
    	for(int i=1; i<=n; i++) scanf("%d", &d[i]);
    	for(int i=1; i<=n; i++) d[i+n]=d[i];
    	s[0]=0; ss[0]=0;
    	for(int i=1; i<=n+n; i++) s[i]=s[i-1]+d[i];
    	for(int i=1; i<=n+n; i++) ss[i]=ss[i-1]+(d[i]+1ll)*d[i]/2;
    	long long ans=-1;
    	for(int i=1; i<=n; i++) {
    		ans = max(ans, calc(s[i+n])-calc(s[i+n]-x));
    	}
    	printf("%lld
    ", ans);
    }
    
  • 相关阅读:
    ES6之Promise用法详解
    Vue项目部署问题及解决方案
    Vue---导航守卫使用方法详解
    深入理解Vue的生命周期
    Bootstrap中datetimepicker日期控件1899年问题解决
    基于Vue-cli 快速搭建项目
    Vue-router的基本用法
    js保留两位小数方法总结
    Vue---父子组件之间的通信
    Vue---自定义组件
  • 原文地址:https://www.cnblogs.com/sahdsg/p/12971039.html
Copyright © 2011-2022 走看看