1. 程式人生 > >洛谷P1083借教室

洛谷P1083借教室

線段樹水題

我們先建一棵線段樹,對於每次借教室相當於區間減,等哪天減到小於零就輸出就行了

這題據說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; }