区間最小遅延セグ木

segenttree seg(N) サイズNのセグ木を宣言 初期値INFなのでちゃんとしといてください

初期化まじでちゃんとしてください

range_add(l,r,x) lからrまでにxを加算

range_set(l,r,x) lからrまでをxに変更

query(l,r) lからrまでの最小値を出力

計算量  全て logN

class segmenttree{
public:
    long long INF = 1e18;
    long long siz = 1;
    vector<long long> v;
    vector<long long> lazy_add;
    vector<long long> lazy_set;
    vector<bool> hav_set;
    segmenttree (long long n){
        siz = 1;
        while(siz < n)siz *= 2;
        v.assign(2*siz,INF);
        lazy_add.assign(2*siz,0);
        lazy_set.assign(2*siz,0);
        hav_set.assign(2*siz,false);
    }
    long long query(long long l,long long r){
        if(l > r)return INF;
        return query(l,r,1,0,siz-1);
    }
    void range_add(long long l,long long r,long long x){
        range_add(l,r,1,0,siz-1,x);
    }
    void range_set(long long l,long long r,long long x){
        range_set(l,r,1,0,siz-1,x);
    }
    void apply_set(long long s,long long x){
        v[s] = x;
        lazy_set[s] = x;
        lazy_add[s] = 0;
        hav_set[s] = true;
    }
    void apply_add(long long s,long long x){
        v[s] += x;
        if(hav_set[s]){
            lazy_set[s] += x;
        }
        else{
            lazy_add[s] += x;
        }

    }
    void push(long long s){
        if(hav_set[s]){
            apply_set(s*2,lazy_set[s]);
            apply_set(s*2+1,lazy_set[s]);
            hav_set[s] = false;
            lazy_set[s] = 0;
        }
        if(lazy_add[s]!=0){
            apply_add(s*2,lazy_add[s]);
            apply_add(s*2+1,lazy_add[s]);
            lazy_add[s] = 0;
        }
    }
    void pull(long long s){
        v[s] = min(v[s*2],v[s*2+1]);
    }
    long long query(long long L,long long R,long long s,long long l,long long r){
        if(r < L || l > R)return INF;
        if(l >= L && r <= R){
            return v[s];
        }
        push(s);
        long long ans = min(
            query(L,R,s*2,l,(l+r)/2),
            query(L,R,s*2+1,(l+r)/2+1,r)
        );
        return ans;
    }
    void range_set(long long L,long long R,long long s,long long l,long long r,long long x){
        if(r < L || l > R)return;
        if(l >= L && r <= R){
            apply_set(s,x);
            return;
        }
        push(s);
        range_set(L,R,s*2,l,(l+r)/2,x);
        range_set(L,R,s*2+1,(l+r)/2+1,r,x);
        pull(s);
    }
    void range_add(long long L,long long R,long long s,long long l,long long r,long long x){
        if(r < L || l > R)return;
        if(l >= L && r <= R){
            apply_add(s,x);
            return;
        }
        push(s);
        range_add(L,R,s*2,l,(l+r)/2,x);
        range_add(L,R,s*2+1,(l+r)/2+1,r,x);
        pull(s);
    } 
};