洛谷P1083借教室
阿新 • • 發佈:2018-12-09
線段樹水題
我們先建一棵線段樹,對於每次借教室相當於區間減,等哪天減到小於零就輸出就行了
這題據說nm暴力可過
程式碼
//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=4000005;
#define ls t[x].s[0]
#define rs t[x].s[1]
#define lb t[x].b[0]
#define rb t[x].b[1]
struct Seg
{
int s[2],b[2];
int asum,lazy;
}t[M];
int n,m;
int a[M],cnt,rt;
bool flag=0;
inline int read()
{
int x=0;char ch=getchar();
while (ch>'9'||ch<'0') ch=getchar();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x;
}
inline void up(int x)
{
t[x].asum=min(t[ls].asum+t[x].lazy,t[rs].asum+t[x].lazy);
if (t[x].asum<0) flag=1;
return ;
}
inline void built(int l,int r,int x)
{
lb=l;rb=r;t[x].lazy=0;
if (l==r)
{
ls=rs=-1;t[x].asum=a[l];
return ;
}
int mid=(l+r)>>1;
ls=++cnt;rs=++cnt;
built(l,mid,ls);built(mid+1,r,rs);
return (void)(up(x));
}
inline void date(int l,int r,int x,int v)
{
if (l<=lb&&rb<=r)
{
t[x].asum+=v;t[x].lazy+=v;
if (t[x].asum<0) flag=1;
return ;
}
int mid=(lb+rb)>>1;
if (l<=mid) date(l,r,ls,v);
if (r>mid) date(l,r,rs,v);
return (void)(up(x));
}
signed main()
{
n=read();m=read();
for (int i=1;i<=n;i++) a[i]=read();
built(1,n,rt);
for (int i=1;i<=m;i++)
{
int sub=read(),l=read(),r=read();
date(l,r,rt,-sub);
if (flag) return cout<<"-1"<<endl<<i,0;
}
return puts("0"),0;
}