제출 #1300143

#제출 시각아이디문제언어결과실행 시간메모리
1300143nathan4690Progression (NOI20_progression)C++20
100 / 100
784 ms69984 KiB
#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define f1(i,n) for(int i=1;i<=n;i++)
#define __file_name ""
using namespace std;
const ll maxn=1e6+5, inf=1e18;

struct Lazy{
    long long add = 0, put = -inf;
    Lazy(long long v1 = 0, long long v2 = -inf): add(v1), put(v2){};
    Lazy operator+(const Lazy &rhs) const{
        // Push a lazy down
        // add first, then put
        if(rhs.put != -inf) return rhs;
        if(put != -inf) return Lazy(0, put + rhs.add);
        return Lazy(add + rhs.add);
    }
};

struct Value{
    int ans = -1e9, len = 0, lpf = 0, lsf = 0;
    ll sum = 0, vpf = -inf, vsf = -inf;
    Value(){};
    Value(long long data){
        ans = len = lpf = lsf = 1;
        sum = data;
        vpf = vsf = data;
    };
    Value operator+(const Value &rhs) const{
        // Merge two nodes
        Value res;
        res.ans = max(ans, rhs.ans);
        if(vsf == rhs.vpf){
            res.ans = max(res.ans, rhs.lpf + lsf);
        }
        res.len = len + rhs.len;
        res.sum = sum + rhs.sum;
        res.vpf = vpf; res.vsf = rhs.vsf;
        if(lpf == len && rhs.vpf == vpf) res.lpf = lpf + rhs.lpf;
        else res.lpf = lpf;
        if(rhs.lsf == rhs.len && vsf == rhs.vsf) res.lsf = lsf + rhs.lsf;
        else res.lsf = rhs.lsf;
        return res;
    }
    Value operator+(const Lazy &rhs) const{
        // Apply lazy to node
        if(rhs.put != -inf){
            Value res;
            res.ans = res.len = res.lpf = res.lsf = len;
            res.vpf = res.vsf = rhs.put;
            res.sum = rhs.put * len;
            return res;
        }
        Value res = *this;
        res.sum += rhs.add * len;
        res.vpf += rhs.add; res.vsf += rhs.add;
        return res;
    }
};

template<class T, class U>
struct SegmentTree{
    int n;
    vector<T> st;
    vector<U> lazy;
    SegmentTree(){};
    SegmentTree(int n): n(n), st(4*n+1), lazy(4*n+1){};
    inline void down(int idx){
        st[idx*2] = st[idx*2] + lazy[idx];
        lazy[idx*2] = lazy[idx*2] + lazy[idx];
        st[idx*2+1] = st[idx*2+1] + lazy[idx];
        lazy[idx*2+1] = lazy[idx*2+1] + lazy[idx];
        lazy[idx] = U();
    }
    void _upd1(int idx, int l, int r, int i, const T &v){
        if(i < l || r < i) return;
        if(l == r){
            st[idx] = v;
            return;
        }
        down(idx);
        int mid = (l + r) / 2;
        _upd1(idx*2, l, mid, i, v);
        _upd1(idx*2+1, mid+1, r, i, v);
        st[idx] = st[idx*2] + st[idx*2+1];
    }
    inline void updatePoint(int position, const T &value){
        _upd1(1,1,n,position,value);
    }
    void _upd2(int idx, int l, int r, int u, int v, const U &w){
        if(v < l || r < u) return;
        if(u <= l && r <= v){
            st[idx] = st[idx] + w;
            lazy[idx] = lazy[idx] + w;
            return;
        }
        down(idx);
        int mid = (l + r) / 2;
        _upd2(idx*2, l, mid, u, v, w);
        _upd2(idx*2+1, mid+1, r, u, v, w);
        st[idx] = st[idx*2] + st[idx*2+1];
    }
    inline void updateRange(int left_, int right_, const U &value){
        _upd2(1,1,n,left_, right_, value);
    }
    T _get(int idx, int l, int r, int u, int v){
        if(v < l || r < u) return T();
        if(u <= l && r <= v) return st[idx];
        down(idx);
        int mid = (l + r) / 2;
        return _get(idx*2, l, mid, u, v) + _get(idx*2+1, mid+1, r, u, v);
    }
    inline T getRange(int left_, int right_){
        return _get(1,1,n,left_, right_);
    }
};

#define SegTree SegmentTree<Value,Lazy>

ll n, q, a[maxn];
SegTree st;

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    if(fopen(__file_name ".inp", "r")){
        freopen(__file_name ".inp", "r", stdin);
        freopen(__file_name ".out", "w", stdout);
    }
    // code here
    cin >> n >> q;
    st = SegTree(n);
    f1(i,n) {
        cin >> a[i];
        st.updatePoint(i, a[i] - a[i-1]);
    }
    while(q--){
        int tp; cin >> tp;
        if(tp == 1){
            ll l, r, s, c; cin >> l >> r >> s >> c;
            st.updateRange(l, l, s);
            st.updateRange(l + 1, r, c);
            st.updateRange(r + 1, r + 1, - s - c * (r - l));
        }else if(tp == 2){
            ll l, r, s, c; cin >> l >> r >> s >> c;
            ll valpi = st.getRange(1, l-1).sum;
            ll valpj = st.getRange(1, r + 1).sum;
            st.updatePoint(l, s - valpi);
            st.updateRange(l + 1, r, Lazy(0, c));
            st.updatePoint(r + 1, valpj - (s + (r - l) * c));
        }else{
            ll l, r; cin >> l >> r;
            cout << max(1, st.getRange(l + 1, r).ans + 1) << '\n';
        }
    }
    return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

Progression.cpp: In function 'int main()':
Progression.cpp:128:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  128 |         freopen(__file_name ".inp", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Progression.cpp:129:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  129 |         freopen(__file_name ".out", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...