这题其实不难,为啥放在cf div2的E呢?
下文中,每个round对怪物造成的净伤害为sum,一个round中对这个怪物的最大伤害为mx,均为负数
这题主要是有个坑点:可能在一个round中会有一个点,它大于整个round结束之后对怪物造成的净伤害。所以,我们需要找出一个round中最大的伤害的点mx。
比如,样例1中,最大伤害点是-100-200-300=600。
因此,我们可以这样思考:如果一个round开始之前,这个怪物的血量h<=mx,那它就会死在这个round,而前面我们需要做的,就是把这个怪物的血线压到mx以下,因此,前面造成的伤害为h+mx(mx为伤害,为负数),而这个伤害只能由净伤害造成,因此,需要的round数为need_r=ceil((h+mx)/(-sum)),也就是说,need_r+1轮内这个怪物必死,然后,再遍历di,找出这个怪物会死在哪个点i,就可以得到答案为need_r*n+i.
注意特判情况,也就是在mx和sum均小于怪物血量h的时候,这个怪物无法被杀死。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+100;
template<typename T>
void read(T&x){
    char ch=getchar();
    ll f=1;
    while(!isdigit(ch)){
        if(ch=='-')f*=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        x=x*10+ch-'0';
        ch=getchar();
    }
    x*=f;
}
template<typename T>
void write(T x){
    if(x<0)putchar('-'),x=-x;
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
//===========================================================
#define int ll
ll h,n;
int d[maxn];
int solve(){
    int mx=0;
    for(int i=1;i<=n;i++){
        d[i]+=d[i-1];
        if(h+d[i]<=0)return i;
        mx=min(mx,d[i]);
    }
    if(d[n]>=0)return -1;
    int need=h+mx;
    //cerr<<"*"<<need<<endl;
    //cerr<<d[n]<<endl;
    int need_r=ceil(1.0*need/(-d[n]));
    //cerr<<need_r<<" "<<need_r*d[n]<<endl;
    h+=need_r*d[n];
    for(int i=1;i<=n;i++){
        if(h+d[i]<=0){
            return need_r*n+i;
        }
    }
    exit(1);
}

signed main(){
    //freopen("in.txt","r",stdin);
    read(h),read(n);
    for(int i=1;i<=n;i++)read(d[i]);
    write(solve());
    return 0;
}