A superhero fights with a monster. The battle consists of rounds, each of which lasts exactly n minutes. After a round ends, the next round starts immediately. This is repeated over and over again.
Each round has the same scenario. It is described by a sequence of n numbers: d1,d2,…,dn (− 1 0 6 10^6 106≤di≤ 1 0 6 10^6 106). The i-th element means that monster’s hp (hit points) changes by the value di during the i-th minute of each round. Formally, if before the i-th minute of a round the monster’s hp is h, then after the i-th minute it changes to h:=h+di.
The monster’s initial hp is H. It means that before the battle the monster has H hit points. Print the first minute after which the monster dies. The monster dies if its hp is less than or equal to 0. Print -1 if the battle continues infinitely.
Input
The first line contains two integers H and n (1≤H≤
1
0
1
2
10^12
1012, 1≤n≤
2
⋅
1
0
5
2⋅10^5
2⋅105). The second line contains the sequence of integers d1,d2,…,dn (
−
1
0
6
≤
d
i
≤
1
0
6
−10^6≤di≤10^6
−106≤di≤106), where di is the value to change monster’s hp in the i-th minute of a round.
Output
Print -1 if the superhero can’t kill the monster and the battle will last infinitely. Otherwise, print the positive integer k such that k is the first minute after which the monster is dead.
Examples
1000 6
-100 -200 -300 125 77 -4
9
1000000000000 5
-1 0 0 0 0
4999999999996
10 4
-3 -6 5 4
-1
题目大意:
给定一个初始高度 H H H,每轮(round)下降需要 n n n分钟,问下降后高度最先小于等于0的时间。
思路:
对于每一轮下降,利用前缀和求出这一轮最后下降多少;因为这一轮下降过程中间可能小球的高度可能小于等于零,所以用
m
n
mn
mn记录这一轮小球最多下降多少。
然后统计小球的下降轮数,因为小球下降轮数越少越安全,所以用二分统计最多可能的下降轮数。然后统计所有时间即可。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,h[200005],H;
int sum[200005];
int mn=0x3f3f3f3f,num=0;
int judge(int mid){//二分统计下降轮数,下降轮数越少越安全
if(H+mid*sum[n]>abs(mn)) return 1;
else return 0;
}
signed main(){//防止爆int
cin>>H>>n;
for(int i=1;i<=n;i++) cin>>h[i],sum[i]=sum[i-1]+h[i],mn=min(mn,sum[i]);//前缀和统计从最开始的地方在第i次后下降的位置
if(sum[n]>=0&&H+mn>0){cout<<"-1\n";return 0;}
int round=0;
if(H+mn>0){
num=H/abs(sum[n]);
int l=1,r=num;
while(l<r){//二分求下降轮数
int mid=(l+r)>>1;
if(judge(mid)) l=mid+1;
else r=mid;
}
round=l;
}
int rest=H-round*abs(sum[n]),ans=0;
ans+=round*n;
for(int i=1;i<=n;i++){
if(rest+sum[i]<=0){
ans+=i;
break;
}
}
cout<<ans<<"\n";
return 0;
}