/* 贪心策略: 如果检查的那天不用加,那就不加 反之加上尽可能多的钱 如何确定这个值? 处理出前缀和,第i天可以加的钱=d-[i+1,n]天里前缀和的最大值 加上这个值后,要再一次更新前缀和数组,用线段树维护前缀和数组即可 */ #include<bits/stdc++.h> using namespace std; #define ll long long #define N 200005 ll n,d,a[N],sum[N]; vector<int>v; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 ll lazy[N<<2],Max[N<<2]; void pushdown(int rt){ lazy[rt<<1]+=lazy[rt]; lazy[rt<<1|1]+=lazy[rt]; Max[rt<<1]+=lazy[rt]; Max[rt<<1|1]+=lazy[rt]; lazy[rt]=0; } void build(int l,int r,int rt){ if(l==r){Max[rt]=sum[l];return;} int m=l+r>>1; build(lson);build(rson); Max[rt]=max(Max[rt<<1],Max[rt<<1|1]); } void update(int L,int R,int v,int l,int r,int rt){ if(L<=l && R>=r){ Max[rt]+=v;lazy[rt]+=v;return; } pushdown(rt); int m=l+r>>1; if(L<=m)update(L,R,v,lson); if(R>m)update(L,R,v,rson); Max[rt]=max(Max[rt<<1],Max[rt<<1|1]); } ll query(int L,int R,int l,int r,int rt){ if(L<=l && R>=r)return Max[rt]; int m=l+r>>1; pushdown(rt); ll res=-0x3f3f3f3f3f3f3f3f; if(L<=m)res=max(res,query(L,R,lson)); if(R>m)res=max(res,query(L,R,rson)); return res; } int main(){ cin>>n>>d; for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<=n;i++){ sum[i]=sum[i-1]+a[i]; if(sum[i]>d){ cout<<-1;return 0; } } build(1,n,1); for(int i=1;i<=n;i++) if(a[i]==0)v.push_back(i); int ans=0; for(auto pos:v){ ll cur=query(pos,pos,1,n,1); if(cur>=0)continue; ans++; ll mx=query(pos,n,1,n,1); ll dif=d-mx; if(dif+cur<0){ cout<<-1<<' ';return 0; } update(pos+1,n,dif,1,n,1); } cout<<ans<<' '; }