[ 模板 ] 线段树区间修改

来源:互联网 发布:linux 混合硬盘 编辑:程序博客网 时间:2024/05/16 00:24
#include <stdio.h>#include <algorithm>using namespace std;int n,m,room[1000001],x,y,c;struct tree{    int mini,lazy;}node[4000001];void pushup(int rt){    node[rt].mini = min(node[rt<<1].mini, node[rt<<1|1].mini);}void pushdown(int l,int r,int rt){    int tmp = node[rt].lazy;    node[rt].lazy=0;    if(!tmp || l==r) return ;    node[rt<<1].mini -= tmp;    node[rt<<1|1].mini -= tmp;    node[rt<<1].lazy = tmp;    node[rt<<1|1].lazy = tmp;}void build(int l,int r,int rt){    if(l==r)    {        node[rt].mini = room[l];        return ;    }    int mid=l+(r-l)/2;    build(l,mid,rt<<1);    build(mid+1,r,rt<<1|1);    pushup(rt);}void update(int l,int r,int v,int sl,int sr,int rt){    if(sl==l && sr==r)    {        node[rt].lazy += v;        node[rt].mini -= v;        return ;    }    int mid = l+(r-l)/2;    if(node[rt].lazy) pushdown(l,r,rt);    if(sr <= mid) update(l, mid, c, sl, sr, rt<<1);    else if(sl > mid) update(mid+1, r, c, sl, sr, rt<<1|1);    else    {        update(l, mid, c, sl, mid, rt<<1);        update(mid+1, r, c, mid+1, sr, rt<<1|1);    }    pushup(rt);}int main(){    scanf("%d%d", &n, &m);    for(int i = 1; i <= n; i++)        scanf("%d", &room[i]);    build(1, n, 1);    for(int i = 1; i <= m; i++)    {        scanf("%d%d%d", &c, &x, &y);        update(1, n, c, x, y, 1);        if(node[1].mini < 0)        {            printf("-1\n%d\n",i);            return 0;        }    }    printf("0\n");    return 0;}
0 0
原创粉丝点击