您的位置:首页 > 其它

2017.3.18【NOIP提高组】模拟赛B组 T1:人类基因组

2017-03-20 20:24 246 查看

【NOIP2013模拟联考15】人类基因组(genes)

Description

L教授最近正在研究一个关于人类基因的项目,基因可以被看作一个长度为N的序列:A0,A1,……,An-1。对于这个基因序列循环移动k位之后,就可以得到一个新的基因序列为:Ak,Ak+1,…,An-1,A0,A1,…,Ak-1。当一个基因序列满足对于任意的前i(1<=i<=n)项和都满足不小于0,我们就称这个基因序列为优质基因序列。

由于L教授最近工作比较繁忙,所以找到了正在实验室闲逛的你,你的任务就是帮L教授统计出所有优质基因序列的个数。

Input

第一行一个整数n,表示基因序列的长度。

第二行n个整数,依次为A0,A1,……,An-1的值。

Output

输出仅一个整数,表示优质基因序列的个数。

Sample Input

输入1:

3

2 2 3

输入2:

5

3 -1 2 -3 4

Sample Output

输出1:

3

【样例1说明】

3个元素的序列:2 2 3,循环移动情况如下:

循环移动0位得到序列:2 2 3,前i项和分别为:2 4 7,符合条件;

循环移动1位得到序列:2 3 2,前i项和分别为:2 5 7;符合条件;

循环移动2位得到序列:3 2 2,前i项和分别为:3 5 7;符合条件;

输出2:

2

Data Constraint

对于30%的数据,满足1<=N<=5,000

对于50%的数据,满足1<=N<=10,000

对于100%的数据,满足1<=N<=1,000,000,-1,000<=Ai<=1,000

题解:

【题目分析】

把给出的序列复制两份构成:

A[0]、A[1]、…、A[n-1]、A
、A[n+1]、…、An+n-1

则循环移动K位后的序列就是上面序列的:A[k],A[k+1],…,A[k+n-1]。

设sum[i]=A[0]+A[1]+…+A[i],则循环K位后序列的任意前p项的和为:sum[k+p]-sum[k-1];

由此可知:判断环移动K位后的序列任意前p项和都不小于0,只判断最小的sum[k+p]与sum[k-1]的差大于等于0即可。

至于找最小的sum[k+p],可以用下列数据结构之一进行优化:

1、线段树:时间复杂度O(2nlog2n);

2、优先队列:时间复杂度O(2nlog2n);

3、单调队列:时间复杂度O(2n);

标程:

var
i,j,k,l,n,m,ans,gb:longint;
a,sum,f1,f2:array[0..1000000] of longint;
begin
assign(input,'genes.in');reset(input);
assign(output,'genes.out');rewrite(output);
readln(n);
for i:=1 to n do
begin
read(a[i]);
sum[i]:=sum[i-1]+a[i];
end;
f1[1]:=1;f2
:=n;
for i:=2 to n do
begin
if sum[i]<sum[f1[i-1]] then
f1[i]:=i
else
f1[i]:=f1[i-1];
end;
for i:=n-1 downto 1 do
begin
if sum[i]<sum[f2[i+1]] then
f2[i]:=i
else
f2[i]:=f2[i+1];
end;
if sum[f1
]>=0 then inc(ans);
for i:=2 to n do
begin
if (sum[f2[i]]-sum[i-1]>=0) and (sum[f1[i-1]]-sum[i-1]+sum
>=0) then inc(ans);
end;
writeln(ans);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: