题目描述

给定一个长度是n的数列A,我们称一个数列是完美的,当且仅当对于其任意连续子序列的和都是正的。现在你有一个操作可以改变数列,选择一个区间[X,Y]满足Ax +Ax+1 +…+ AY<0,1<X<=Y<n,令S=Ax +Ax+1 +…+ AY,对于Ax-1和AY+1分别加上S,Ax和AY分别减去S(如果X=Y就减两次)。问最少几次这样的操作使得最终数列是完美的。

输入输出格式

输入格式:

第一行一个数n,以下n个数。

【数据规模】

对于20%的数据,满足1≤N≤5;

对于100%的数据,满足1≤N≤10^5; 1≤|A[i]|≤2^31-1。

输出格式:

一个数表示最少的操作次数,如果无解输出-1。

输入输出样例

输入样例#1:

5
13
-3
-4
-5
62
输出样例#1:

2

说明

【样例解释】

首先选择区间[2,4],之后数列变成1,9,-4,7,50,然后选择[3,3],数列变成1,5,4,3,50

Solution:

  本题贼有意思。

  用$s_i$表示$i$的前缀和,那么$s_y-s_{x-1}=T$表示的就是区间$[x,y]$的和,然后我们按照题目中的操作去搞,$a_{x-1}+T,a_{x}-T,a_{y}-T,a_{y+1}+T$,不难发现$s_x,s_y$实际上不变,然后因为$s_y=s_{x-1}+T$则操作等价于交换了$s_{x-1},s_{y}$两值。我们要使得$a_i$均为正数,就得让前缀和单调上升,那么很显然当$s_i\leq 0$或者$s_i=s_j,i\neq j$时无解,由于我们只关心前缀和的大小而非具体的值,所以直接对其离散化,然后就是建边统计一下各个环内的交换次数就好了。

代码:

#include<bits/stdc++.h>
#define il inline
#define ll long long
#define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--)
using namespace std;
const int N=2e5+;
int n,cnt,ans,to[N],net[N],h[N];
ll *q[N],s[N];
bool vis[N]; il int gi(){
int a=;char x=getchar();bool f=;
while((x<''||x>'')&&x!='-')x=getchar();
if(x=='-')x=getchar(),f=;
while(x>=''&&x<='')a=(a<<)+(a<<)+x-,x=getchar();
return f?-a:a;
} il bool cmp(const ll *a,const ll *b){return *a < *b;} il void add(int u,int v){to[++cnt]=v,net[cnt]=h[u],h[u]=cnt;} il void dfs(int u){
for(int i=h[u];i;i=net[i])
if(!vis[to[i]]) vis[to[i]]=,ans++,dfs(to[i]);
} int main(){
n=gi();
For(i,,n) {
s[i]=s[i-]+gi(),q[i]=&s[i];
if(s[i]<=)puts("-1"),exit();
}
sort(q+,q+n+,cmp);
ll lst=-;
For(i,,n)
if(*q[i]!=lst) lst=*q[i],*q[i]=++cnt;
else *q[i]=cnt,puts("-1"),exit();
For(i,,n) if(i!=s[i]) add(i,s[i]);
For(i,,n) if(!vis[i]) vis[i]=,dfs(i);
cout<<ans;
return ;
}

P1667 数列的更多相关文章

  1. 洛谷P1667/[10.22 模拟赛] 数列 (思维+模拟)

    洛谷P1667 数列 题目描述 给定一个长度是n的数列A,我们称一个数列是完美的,当且仅当对于其任意连续子序列的和都是正的.现在你有一个操作可以改变数列,选择一个区间[X,Y]满足\(A_X +A_{ ...

  2. 【洛谷 P1667】 数列 (贪心)

    题目链接 对于一个区间\([x,y]\),设这个区间的总和为\(S\) 那么我们在前缀和(设为\(sum[i]\))的意义上考虑到原操作其实就是\(sum[x−1]+=S\) , \(sum[x]+S ...

  3. C#求斐波那契数列第30项的值(递归和非递归)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  4. BZOJ1500[NOI2005]维修数列

    Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一 ...

  5. PAT 1049. 数列的片段和(20)

    给定一个正数数列,我们可以从中截取任意的连续的几个数,称为片段.例如,给定数列{0.1, 0.2, 0.3, 0.4},我们有(0.1) (0.1, 0.2) (0.1, 0.2, 0.3) (0.1 ...

  6. 斐波拉契数列加强版——时间复杂度O(1),空间复杂度O(1)

    对于斐波拉契经典问题,我们都非常熟悉,通过递推公式F(n) = F(n - ) + F(n - ),我们可以在线性时间内求出第n项F(n),现在考虑斐波拉契的加强版,我们要求的项数n的范围为int范围 ...

  7. fibonacci数列(五种)

    自己没动脑子,大部分内容转自:http://www.jb51.net/article/37286.htm 斐波拉契数列,看起来好像谁都会写,不过它写的方式却有好多种,不管用不用的上,先留下来再说. 1 ...

  8. js中的斐波那契数列法

    //斐波那契数列:1,2,3,5,8,13…… //从第3个起的第n个等于前两个之和 //解法1: var n1 = 1,n2 = 2; for(var i=3;i<101;i++){ var ...

  9. 洛谷 P1182 数列分段Section II Label:贪心

    题目描述 对于给定的一个长度为N的正整数数列A[i],现要将其分成M(M≤N)段,并要求每段连续,且每段和的最大值最小. 关于最大值最小: 例如一数列4 2 4 5 1要分成3段 将其如下分段: [4 ...

随机推荐

  1. 解决Entity Framework查询匿名对象后的跨域访问的一种方式

    在Entity Framework中,可以使用lambda表达式进行对数据的查询,而且可以将查询结果直接映射为对象或者对象列表,这极大的提高的开发速度,并且使数据层的数据更加方便处理和传递.但是很多时 ...

  2. JS中String对象常用的方法

    1.  stringObject.charAt(index) 参数:index 必需,即字符在字符串中的下标.  返回值:   返回在指定位置的字符.返回的字符是长度为 1的字符串.(length属性 ...

  3. 「专题训练」k-Tree(CodeForces Round #247 Div.2 C)

    题意与分析(Codeforces-431C) 题意是这样的:给出K-Tree--一个无限增长的树,它的每个结点都恰有\(K\)个孩子,每个节点到它\(K\)个孩子的\(K\)条边的权重各为\(1,2, ...

  4. VIN码识别:毫秒间99%精准识别

    科技改变生活.几年前,人工智能还仅是一个噱头,现在已逐渐融入我们的工作和生活,代替了一些重复性的.繁杂的人工劳动,在提高工作效率的同时,提升了客户体验. 车架号也叫VIN码,由17位数字和字母混合组成 ...

  5. linux部署maven

    1.下载安装包 https://maven.apache.org/download.cgi 2.解压,并配置环境变量 vim /etc/profile export MAVEN_HOME=maven目 ...

  6. 韦大仙--python对文件操作 2--写入与修改

    请大家看一段代码: yesterday2是我之前上个帖子创建的文件,为了方便大家看清我把本来的代码复制到下面: coding=utf-8 f=open("yesterday2",& ...

  7. C 进制 类型说明符 位运算 char类型

    一 进制 1. 什么是进制 是一种计数的方式 数值的表示形式 2. 二进制 1> 特点: 只有0和1 逢2进1 2> 书写格式: 0b或者0B开头 3> %d 以带符号的十进制形式输 ...

  8. Linux搭建mysql、apache、php服务总结

    本随笔文章,由个人博客(鸟不拉屎)转移至博客园 写于:2018 年 04 月 22 日 原地址:https://niaobulashi.com/archives/linux-mysql-apache- ...

  9. 统计hive库表在具体下所有分区大小

    1 查询具体表分区大小,以字节展示 hadoop fs -du /user/hive/warehouse/treasury.db/dm_user_excercise > dm_user_exce ...

  10. ELK部署方法

    最近经理开会说公司要安装ELK日志管理让我们搭建ELK,下面是我搭建步骤和流程,用三台机测试机器搭建的. 软件包我都 给你们放/usr/local/src/elk目录下安装目录都放在/usr/loca ...