借教室

借教室

https://ac.nowcoder.com/acm/problem/16564

题意

有一个长度为的区间,有次操作,每次使得区间的值减去

分析

我们每次只需要做两种操作:

  1. 询问区间最小值。
  2. 使得区间减去

线段树模板。

#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define int long long
const int inf = 0x3f3f3f3f;
const int maxn = 1001110;
const int M = 1e9+7;
int n,m;

int a[maxn];

struct tree_node
{
    int l,r,sum,lazy;
};

struct segtree
{
    tree_node t[maxn*4];
    void pushup(int k)
    {
        t[k].sum = min(t[k*2].sum,t[k*2+1].sum);
    }
    void pushdown(int k)
    {
        if(t[k].lazy)
        {
            t[k*2].lazy += t[k].lazy;
            t[k*2+1].lazy += t[k].lazy;
            t[k*2].sum -= t[k].lazy;
            t[k*2+1].sum -= t[k].lazy;
            t[k].lazy = 0;
        }
    }
    void build(int k,int l,int r)        //建树
    {    
        t[k].l = l,t[k].r = r;
        if(l == r)
        {
            t[k].sum = a[l];
            return;
        }
        int mid = (l+r)/2;
        build(k*2,l,mid);
        build(k*2+1,mid+1,r);
        pushup(k);
    }
    void update(int k,int l,int r,int x)        //区间更新
    {  
        if(l > r) return;
        if(l <= t[k].l && t[k].r <= r)
        {
            t[k].sum -= x;
            t[k].lazy += x;
            return;
        }
        pushdown(k);
        if(t[k*2].r >= l) update(k*2,l,r,x);
        if(t[k*2+1].l <= r) update(k*2+1,l,r,x);
        pushup(k);
    }
    int query(int k,int l,int r)            //查询区间最小值
    {
        if(l > r) return 0;
        if(l <= t[k].l && t[k].r <= r)
        {
            return t[k].sum;
        }
        int res = inf;
        pushdown(k);
        if(t[k*2].r >= l) res =  min(res,query(k*2,l,r));
        if(t[k*2+1].l <= r) res = min(res,query(k*2+1,l,r));
        return res;
    }
}st;

vector<int> ans;

signed main()
{   
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>m;
    for(int i = 1; i <= n; i++)
    {
        cin>>a[i];
    }
    st.build(1,1,n);
    int d,s,t;
    for(int i = 1; i <= m; i++)
    {
        cin>>d>>s>>t;
        int mi = st.query(1,s,t);
        if(mi >= d)
        {
            st.update(1,s,t,d);
        }
        else
        {
            cout<<-1<<'\n'<<i<<'\n';
            return 0;
        }
    }
    cout<<0<<'\n';
    return 0;
}
全部评论

相关推荐

不愿透露姓名的神秘牛友
07-03 17:37
点赞 评论 收藏
分享
找个工作&nbsp;学历是要卡的&nbsp;要求是高的&nbsp;技能不足是真的&nbsp;实习经验是0的&nbsp;简历无处可写是事实的&nbsp;钱不好赚是真的&nbsp;想躺平又不敢躺&nbsp;也不甘心躺&nbsp;怕自己的灵感和才华被掩埋甚至从未被自己发现&nbsp;又质疑自己是否真正有才华
码农索隆:你现在啊,你心里都明白咋回事,但是你没办法改变现状,一想到未来,你又没有信心狠下心来在当下努力。 得走出这种状态,不能一直困在那里面,哪不行就去提升哪,你一动不动那指定改变不了未来,动起来,积少成多才能越来越好
点赞 评论 收藏
分享
屌丝逆袭咸鱼计划:心态摆好,man,晚点找早点找到最后都是为了提升自己好进正职,努力提升自己才是最关键的😤难道说现在找不到找的太晚了就炸了可以鸡鸡了吗😤早实习晚实习不都是为了以后多积累,大四学长有的秋招进的也不妨碍有的春招进,人生就这样
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-04 18:25
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务