제출 #1157724

#제출 시각아이디문제언어결과실행 시간메모리
1157724vicvicProgression (NOI20_progression)C++20
0 / 100
517 ms1114112 KiB
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <cstdint>
#include <cassert>
#define cin f
#define cout g
#define int long long
using namespace std;
ifstream f ("test.in");
ofstream g ("test.out");
const int NMAX=3e5;
int v[NMAX+5], n, q;
class SegTree
{
public:
    struct node
    {
        int l, r, sm, pref, suf, pref_len, suf_len, lazy, lazy2, hi, reset, len;
        node ()
        {
            this -> l=this -> r=this -> sm=this -> pref=this -> suf=this -> pref_len=this -> suf_len=this -> lazy=this -> lazy2=this -> hi=this -> reset=this -> len=0;
        }
    } t[NMAX*4+5];
    node merge (node b, node a)
    {
        node ret;
        ret.l=b.l;
        ret.len=b.len+a.len;
        ret.hi=max (b.hi, a.hi);
        if (b.suf==a.pref)
            ret.hi=max (ret.hi, b.suf_len+a.pref_len);
        ret.r=a.r;
        ret.sm=a.sm+b.sm;
        ret.pref=b.pref;
        ret.suf=a.suf;
        ret.pref_len=b.pref_len;
        ret.suf_len=a.suf_len;
        if (b.pref==a.pref && b.pref_len==b.len) ret.pref_len+=a.pref_len;
        if (a.suf==b.suf && a.suf_len==a.len) ret.suf_len+=b.suf_len;
        return ret;
    }
    void actbuild (int nod, int st, int dr)
    {
        if (st==dr)
        {
            t[nod].hi=t[nod].pref_len=t[nod].suf_len=1;
            t[nod].sm=t[nod].pref=t[nod].suf=v[st]-v[st-1];
            t[nod].l=st;
            t[nod].r=dr;
            t[nod].len=1;
        }
        else
        {
            int mij =(st+dr) >> 1;
            actbuild (nod*2, st, mij);
            actbuild (nod*2+1, mij+1, dr);
            t[nod]=merge (t[nod*2], t[nod*2+1]);
        }
    }
    void build (int st, int dr)
    {
        actbuild (1, st, dr);
    }
    void prop (int nod)
    {
        if (t[nod].reset)
        {
            t[nod].suf_len=t[nod].pref_len=t[nod].hi=t[nod].len;
            t[nod].pref=t[nod].suf=t[nod].lazy2;
            t[nod].reset=0;
            t[nod].sm=t[nod].lazy2*(t[nod].len);
            if (t[nod].l!=t[nod].r)
            {
                t[nod*2].lazy2=t[nod].lazy2;
                t[nod*2+1].lazy2=t[nod].lazy2;
                t[nod*2].reset=t[nod*2+1].reset=1;
                t[nod*2].lazy=t[nod*2+1].lazy=0;
            }
        }
        else
        {
            t[nod].pref+=t[nod].lazy;
            t[nod].suf+=t[nod].lazy;
            t[nod].sm+=t[nod].lazy*(t[nod].len);
            if (t[nod].l!=t[nod].r)
            {
                if (!t[nod*2].reset) t[nod*2].lazy+=t[nod].lazy;
                else t[nod*2].lazy=0, t[nod*2].lazy2+=t[nod].lazy;
                if (!t[nod*2+1].reset) t[nod*2+1].lazy+=t[nod].lazy;
                else t[nod*2+1].lazy=0, t[nod*2+1].lazy2+=t[nod].lazy;
            }
        }
        t[nod].lazy=t[nod].lazy2=0;
    }
    void actupdate_type1 (int nod, int st, int dr, int stq, int drq, int val)
    {
        prop (nod);
        if (stq<=st && dr<=drq)
        {
            if (t[nod].reset) t[nod].lazy2+=val;
            else t[nod].lazy+=val;
            prop (nod);
        }
        else
        {
            int mij = (st+dr) >> 1;
            if (drq<=mij)
                actupdate_type1 (nod*2, st, mij, stq, drq, val);
            else if (stq>mij)
                actupdate_type1 (nod*2+1, mij+1, dr, stq, drq, val);
            else actupdate_type1 (nod*2, st, mij, stq, drq, val), actupdate_type1 (nod*2+1, mij+1, dr, stq, drq, val);
            prop (nod*2);
            prop (nod*2+1);
            t[nod]=merge (t[nod*2], t[nod*2+1]);
        }
    }
    void update_type1 (int st, int dr, int val)
    {
        if (!(st >= 1 && dr <= n && st <= dr))
            return;
        actupdate_type1 (1, 1, n, st, dr, val);
    }
    void actupdate_type2 (int nod, int st, int dr, int stq, int drq, int val)
    {
        prop (nod);
        if (stq<=st && dr<=drq)
        {
            t[nod].lazy2=val;
            t[nod].reset=1;
            t[nod].lazy=0;
            prop (nod);
        }
        else
        {
            int mij = (st+dr) >> 1;
            if (drq<=mij)
                actupdate_type2 (nod*2, st, mij, stq, drq, val);
            else if (stq>mij)
                actupdate_type2 (nod*2+1, mij+1, dr, stq, drq, val);
            else actupdate_type2 (nod*2, st, mij, stq, drq, val), actupdate_type2 (nod*2+1, mij+1, dr, stq, drq, val);
            prop (nod*2);
            prop (nod*2+1);
            t[nod]=merge (t[nod*2], t[nod*2+1]);
        }
    }
    void update_type2 (int st, int dr, int val)
    {
        if (!(st >= 1 && dr <= n && st <= dr))
            return;
        actupdate_type2 (1, 1, n, st, dr, val);
    }
    node actquery (int nod, int st, int dr, int stq, int drq)
    {
        prop (nod);
        if (stq<=st && dr<=drq)
        {
            return t[nod];
        }
        else
        {
            prop (nod*2);
            prop (nod*2+1);
            int mij = (st+dr) >> 1;
            if (drq<=mij)
                return actquery (nod*2, st, mij, stq, drq);
            else if (stq>mij)
                return actquery (nod*2+1, mij+1, dr, stq, drq);
            else return merge (actquery (nod*2, st, mij, stq, drq), actquery (nod*2+1, mij+1, dr, stq, drq));
        }
    }
    node query (int st, int dr)
    {
        if (!(st>=1 && dr<=n && st<=dr))
            return node ();
        return actquery (1, 1, n, st, dr);
    }
};
SegTree aint;
int32_t main ()
{
    ios :: sync_with_stdio (0);
    cin.tie (nullptr);
    cin >> n >> q;
    for (int i=1;i<=n;i++)
    {
        cin >> v[i];
    }
    v[0]=0;
    aint.build (1, n);
    while (q--)
    {
        int type, st, dr;
        cin >> type >> st >> dr;
        if (type==3)
        {
            if (st==dr)
            {
                cout << 1 << "\n";
            }
            else cout << aint.query (st+1, dr).hi+1 << "\n";
        }
        else if (type==1)
        {
            int s, c;
            cin >> s >> c;
            aint.update_type1 (st, st, s);
            if (st<dr) aint.update_type1 (st+1, dr, c);
            if (dr<n) aint.update_type1 (dr+1, dr+1, -(s+(dr-st)*c));
        }
        else
        {
            int s, c;
            cin >> s >> c;
            int s2=0;
            if (dr<n) s2=aint.query (1, dr+1).sm;
            if (st>1)
            {
                int x=aint.query (1, st-1).sm;
                aint.update_type2 (st, st, s-x);
            }
            else
            {
                aint.update_type2 (1, 1, s);
            }
            if (st<dr)
            {
                aint.update_type2 (st+1, dr, c);
            }
            if (dr<n)
            {
                aint.update_type2 (dr+1, dr+1, s2-(s+(dr-st)*c));
            }
        }
    }
    return 0;
}
#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...