【题解】Dvoniz [COCI2011]

传送门:\(\text{Dvoniz [COCI2011] [P5922]}\)

数据\(\text{COCI}\) 官网 提供。

【题目描述】

对于一个长度为 \(2 \times K\) 的序列,如果它的前 \(K\) 个元素之和小于等于 \(S\) 且后 \(K\) 个之和也小于等于 \(S\),我们则称之为 \(\text{interesting}\)。现给定一个长度为 \(N\) 的序列 \(a\),要求输出以每个元素开头能找到的最长 \(\text{interesting}\) 序列的长度。

【输入】

第一行两个整数 \(N,S\)。

接下来 \(N\) 行,每行一个正整数,第 \(i\) 行表示序列中的第 \(i\) 个元素 \(a_i\)。

【输出】

输出共 \(N\) 行,每行一个整数,第 \(i\) 行表示以 \(a_i\) 开头的最长的 \(\text{interesting}\)序列。如果不存在,则输出 \(0\)。

【样例】

样例输入:
5 10000
1
1
1
1
1 样例输出:
4
4
2
2
0

【数据范围】

\(100 \%:\) \(2 \leqslant N \leqslant 10^5,\) \(1 \leqslant S,a_i \leqslant 2 \times 10^9\)


【分析】

一道灰常 \(\text{interesting}\) 的题。

蒟蒻英语差没有细看官方题解,貌似是 \(O(nlogn)\) 的 \(set\),我自己 \(yy\) 了一种 \(O(n)\) 的神奇算法。

设以 \(a[i]\) 为起点的最长合法序列的中点为 \(mid_i\)(前半段为 \([i,mid]\),后半段为 \([mid+1,mid*2-i+1]\)),则 \(ans_i=2(mid_{i}-i+1)\)。

假设现已求出了 \(mid_{i-1}\),考虑 \(mid_i\) 与之有何联系,是否可以继承,如图:

由于 \(mid_{i-1}\) 左右两边的绿色部分都小于等于 \(S\),那么向前推移了一位的 \(i\) 以 \(mid_{i-1}\) 为中点也可以构成合法序列,如下图(易知两边的蓝色部分都一定小于等于 \(S\) ):

所以对于任意 \(i \in [2,n]\),都有 \(mid_{i-1} \leqslant mid_{i}\) 。

那么就可以用一个变量 \(p\) 来维护 \(mid\),从 \(1\) 开始不断地向后移动。

但有可能 \(mid[i-1]\) 并非是以 \(a[i]\) 开头的最优解,继续考虑对每个 \(i\) 求出最大的 \(mid\):

分开处理合法序列的左右两边,当 \(i\) 固定时,如果只看左边是否合法的话,那么从第一个不合法的位置开始,后面的都不合法(这不是理所当然的嘛),所以直接从 \(mid_{i-1}\) 开始向后暴力移动 \(p\)(也可以二分,但不便于后面的证明),扫到不合法的位置时就结束。此时在 \([mid_{i-1},p]\) 中任取一个位置作为 \(mid_{i}\) 都可以满足序列左边合法,现在开始处理右边。

右边对于 \(p\) 的移动是不具有单调性的,那么就暴力往回移动 \(p\),找到第一个使得右边序列合法的位置,此时 \(p\) 停留的位置必定是 \(mid_{i}\) 的最优值。

暴力,暴力,全都是暴力。对于每次 \(i\) 都要把 \(p\) 向后移动若干位置再移回来,时间复杂度似乎为 \(O(n^2)\),但实际上是线性的,可以几十 \(ms\) 轻松跑过(\(n\) 方过百万)。

【时间复杂度证明】

对于每个 \(i\),设 \(p\) 从 \(mid_{i-1}\) 开始向后移动了 \(x_{i}\),又从 \(mid_{i-1}+x_{i}\) 开始向前移回去了 \(y_{i}\),那么总时间复杂度可以表示为 \(\Theta=\sum_{i=1}^{n} (x_{i}+y_{i})\) —— ①。

对于每个 \(i\),\(p\) 从 \(mid_{i-1}\) 开始移动了 \(x_{i}-y_{i}\) 后到达了 \(mid_{i}\),那么 \(mid_{i}\) \((i \in [1,n])\) 的总移动距离就可以表示为 \(\sum_{i=1}^{n} (x_{i}-y_{i})\) 。

又因为 \(mid_{i}\) 具有决策单调性,必定是从 \(1\) 移到 \(n\),所以总移动距离应为 \(n\),即:\(n=\sum_{i=1}^{n} (x_{i}-y_{i})\) —— ②。

由于序列 \([mid_{i-1},mid_{i-1}+x_{i}]\) 中元素之和一定是小于等于 \(S\) 的,那么取其中点 \(M(mid_{i-1}+\frac{x_{i}}{2})\),一定可以使得 \(M\) 两边都合法,即 \(mid_{i} \geqslant M\),于是有 \(mid_{i-1}+x_{i}-y_{i} \geqslant mid_{i-1}+\frac{x_{i}}{2}\),即 \(y_{i} \leqslant \frac{x_{i}}{2}\) —— ③。

由②③可知:

\(n=\sum_{i=1}^{n} (x_{i}-y_{i}) \geqslant \sum_{i=1}^{n} \frac{x_{i}}{2}\),即 \(\sum_{i=1}^{n} \frac{3}{2}x_{i} \leqslant 3n\) 。

由①③可知:

\(\Theta=\sum_{i=1}^{n} (x_{i}+y_{i}) \leqslant \sum_{i=1}^{n} \frac{3}{2}x_{i}\) 。

于是有 \(\Theta \leqslant 3n\) 。

时间复杂度得证,为 \(O(n)\) 。

(这样看来,向后移时的二分貌似都没必要写了)

另外,有个 \(\text{julao}\) 认为上述证明有问题,但具体她又说不清(这不是在扯淡么),如有不严谨处欢迎指出。

【Code】

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#define LL long long
#define Re register int
using namespace std;
const int N=1e5+5;
int n,s,a[N];LL S[N];
inline void in(Re &x){
int f=0;x=0;char c=getchar();
while(c<'0'||c>'9')f|=c=='-',c=getchar();
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
x=f?-x:x;
}
inline int judge1(Re i,Re mid){return S[mid]-S[i-1]<=s;}
//judge1()判断序列前半段
inline int judge2(Re i,Re mid){return S[(mid<<1)-i+1]-S[mid]<=s;}
//judge2()判断序列前半段
int main(){
// freopen("b.in","r",stdin);
// freopen("b.out","w",stdout);
in(n),in(s);
for(Re i=1;i<=n;++i)in(a[i]),S[i]=S[i-1]+a[i];
Re p=0;S[n+1]=S[n+2]=1e18;//为防止玄学错误,先把最后面的覆盖一下
while((p+1<<1)<=n&&judge1(1,p+1))++p;//预处理出第一个mid
while(p&&!judge2(1,p))--p;
printf("%d\n",(p<<1));
for(Re i=2;i<=n;++i){
// if(p<i-1)p=i-1;//这句可加可不加
while((p+1<<1)-i+1<=n&&judge1(i,p+1))++p;//向后移时注意判断右边界不能超过n
while(p>=i&&!judge2(i,p))--p;//向前移回去,找到最大的合法mid_i
printf("%d\n",(p-i+1)<<1);//输出为长度
}
fclose(stdin);
fclose(stdout);
return 0;
}

【题解】Dvoniz [COCI2011]的更多相关文章

  1. 【题解】Ples [COCI2011]

    [题解]Ples [COCI2011] 依旧是没有传送门,只有提供了数据的官网. [题目描述] \(N\) 个汉子和 \(N\) 个妹纸一起参加舞会,跳舞时只能是一个汉子一个妹纸配对,现在给出每个人的 ...

  2. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  3. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  4. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  5. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  6. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  7. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  8. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  9. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

随机推荐

  1. ASP.NET Core基于K8S的微服务电商案例实践--学习笔记

    摘要 一个完整的电商项目微服务的实践过程,从选型.业务设计.架构设计到开发过程管理.以及上线运维的完整过程总结与剖析. 讲师介绍 产品需求介绍 纯线上商城 线上线下一体化 跨行业 跨商业模式 从0开始 ...

  2. 网上售卖几百一月的微信机器,Python几十行代码就能搞定

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 故事胶片 PS:如有需要Python学习资料的小伙伴可以加点击下方链 ...

  3. 使用CAD快速看图如何将图纸打印和预览?

    有相关CAD工作经验的小伙伴们都知道,绘制完CAD图纸后是需要借助CAD看图工具来进行查看图纸的,其实CAD快速看图中不仅能够对图纸进行查看,还能够将CAD图纸进行打印出来.但是有很多的伙伴不知道要怎 ...

  4. NumPy实现数组的拼接和分裂

    一.数组的拼接 import numpy as np x=np.array([,,]) x2=np.array([,,])np.concatenate([x,x2]) 输出:array([1, 2, ...

  5. 一文解读ITIL (转)

    首先声明自己不是ITIL方面的专家,特别是具体的规范细节,后面论述如有不当,请指正.但我为什么会提起它?主要是因为它和运维(IT服务管理)相关性太大了.早起的运维完全就是以ITIL来蓝本构建的,在当时 ...

  6. ubuntu 查看软件包中的内容 (已经安装)

    在 使用 apt 进行安装软件的时候,我们要经常判断,软件安装了什么和安装到什么地方.这时候 我们要使用 dpkg -L 命令来进行查看: 同样 在 fedora 上可以使用 rpm -ql iper ...

  7. Ubuntu 镜像制作 官方教程

    rufus工具下载:下载链接 官方教程:官方教程链接 软件界面预览: 资源来源自网络,如果对您有帮助,请点击推荐~. 我尝试了这个方法可以用.电脑重启时,选择从U盘启动,就能安装系统. 参考链接: h ...

  8. 在python的虚拟环境venv中使用gunicorn

    昨天遇到的问题,一个服务器上有好几个虚拟机环境. 我active进一个虚拟环境,安装了新的三方库之后, 使用gunicorn启动django服务, 但还是死活提示没有安装这个三方库. 一开始没有找到原 ...

  9. 05justify-content

    display: flex; 的默认轴是x轴 justify-content: 设置主轴上的子元素排列的方式 所以在使用之前要确定好哪一个是主轴 /* justify-content:flex-sta ...

  10. NOIP 2011 计算系数

    洛谷 P1313 计算系数 洛谷传送门 JDOJ 1747: [NOIP2011]计算系数 D2 T1 JDOJ传送门 Description 给定一个多项式(ax + by)k,请求出多项式展开后x ...