线段树求调
查看原帖
线段树求调
917407
hitori__楼主2023/4/5 11:45
我的思路是用线段树维护区间最小值,每个客户输入后先进行区间查询,如果区间最小值大于客户要求的教室数量就标记
#include <iostream>
#include <vector>
#define ls p<<1
#define rs p<<1|1
#define lsm tree[ls].min
#define rsm tree[rs].min
#define pm tree[p].min
using namespace std;

typedef struct Tree{
    int l,r;
    int min;
    int lazy;
}Tree;

int n,m;
vector<int> a;   //原数组
vector<Tree> tree;  //线段树

void build(int l, int r, int p)
{
    tree[p] = {l, r, INT32_MAX, 0};
    if(l == r) pm = a[l];
    else{
        int m = l + r >> 1;
        build(l, m, ls);
        build(m+1, r, rs);
        pm = min(lsm, rsm);
    }
}

void pushdown(int p)
{
    int k = tree[p].lazy;
    if(k){
        lsm -= k;
        rsm -= k;
        tree[ls].lazy += k;
        tree[rs].lazy += k;
        tree[p].lazy = 0;
    }
}

void update(int l, int r, int k, int p)
{
    if(tree[p].l>=l && tree[p].r<=r){
        pm -= k;
        tree[p].lazy += k;
    }else{
        pushdown(p);
        int m = tree[p].r + tree[p].l >> 1;
        if(m >= l) update(l,r,k,ls);
        if(m < r) update(l,r,k,rs);
        pm = min(lsm, rsm);
    }
}

int Q(int l, int r, int p)
{
    if(tree[p].l>=l && tree[p].r<=r)
        return pm;
    else{
        pushdown(p);
        int m = tree[p].r + tree[p].l >> 1;
        int lm,rm;
        if(m >= l) lm = Q(l,r,ls);
        if(m < r) rm = Q(l,r,rs);
        return min(lm, rm);
    }
}

int main()
{
    cin >> n >> m;
    int flag = 1;   //记录是否有需要修改的客户,1表示不需要修改
    int res = 0;
    a.resize(n+1);
    tree.resize(n<<2);
    for(int i=1; i<=n; i++) cin >> a[i];
    build(1, n, 1);
    while(m--){
        int d,s,t;
        cin >> d >> s >> t;
        if(!flag) continue;
        int q = Q(s,t,1);
        if(q >= d){
            res++;
            update(s,t,d,1);
        }
        else{
            flag = 0;
            res++;
        }
    }
    if(flag) cout << 0;
    else{
        cout << -1 << endl;
        cout << res << endl;
    }
    return 0;
}
2023/4/5 11:45
加载中...