P1083 借教室

二分+前綴和,以後看

//拿來複習線段樹了 
#include<bits/stdc++.h>
#define mx 1000005
using namespace std;
int a[mx];
int n,m;
int read()//加快讀滿分 
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0' || ch>'9') 
    {
        if(ch==-1)f=-1;
        ch=getchar();   
    }
    while(ch>='0' && ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
struct Tree{
    int l,r,mn,flg;
}tre[mx<<2];
//修改帶詢問 ,維護區間最小值 
void pushup(int rt)
{
    tre[rt].mn=min(tre[rt<<1].mn,tre[rt<<1|1].mn);
}
void build(int rt,int L,int R)
{
    tre[rt].l=L;
    tre[rt].r=R;
    if(L==R){
        tre[rt].mn=a[L];
        return;
    }
    int mid=(L+R)>>1;
    build(rt<<1,L,mid);
    build(rt<<1|1,mid+1,R);
    pushup(rt);
}
void pushdown(int rt)
{
    if(tre[rt].flg)
    {
        tre[rt<<1].mn-=tre[rt].flg;
        tre[rt<<1|1].mn-=tre[rt].flg;
        tre[rt<<1].flg+=tre[rt].flg;//////////////一開始寫成了+ 
        tre[rt<<1|1].flg+=tre[rt].flg;  
        tre[rt].flg=0;
    }   
} 
void update(int rt,int L,int R,int v)
{
    if(L<=tre[rt].l && R>=tre[rt].r)
    {
        tre[rt].mn-=v;//////////////一開始寫成了+ 
        tre[rt].flg+=v;
        return;
    }
    pushdown(rt);
    int mid=(tre[rt].l+tre[rt].r)>>1;
    if(L<=mid)
        update(rt<<1,L,R,v);
    if(R>mid)
        update(rt<<1|1,L,R,v);
    pushup(rt);
} 
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        a[i]=read();
    build(1,1,n);
    int v,L,R;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&v,&L,&R);
        update(1,L,R,v);
        if(tre[1].mn<0) 
        {
            printf("%d\n%d\n",-1,i);
            return 0;
        }
    }
    printf("%d\n",0);
    return 0;
}
10 10
42323424 633675939 990396626 965164370 965164370 
965164370 972489810 619351082 619351082 0

586780256 2 9
316471206 3 7
42323424 1 3
8081621 3 9
36667522 3 7
110729 3 6
4572259 2 9
7436169 7 9
3834281 3 9
8646496 4 9
-1
6
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章