間隔履歴値のメモ - セグメントツリー

CPUモニタ
シーケンス上のメンテナンス作業に:
1、範囲プラス
2、ゾーンの割り当て
3、最大間隔
4、間隔値履歴

セグメントツリーのメンテナンスを使って+マークは、全てのイベントがノードレコードで発生しました。

変更操作は、次の追加、変更とみなすことができるならば、我々は、セグメントのツリーノードに気づきました。

そして、ノードに高々2のマーク長に。

集合\(\テキスト{追加} \ ) マークは、ノードの実際の値を増加させるために、\(\ MOD {テキスト}は\)カバーです。
録音考えてみましょう(\テキスト{追加} \ \ ) そのすべての祖先のマーク\(\テキスト{追加} \ ) マーカー、達成可能な最大の歴史。(\ \テキスト{モッド} \ ) と同様。
以下のように時系列音符マーク発生時刻前分散子ノードに印、およびを組み合わせることとき:

またフラグが起因し、一方で、分散化とき(\ \テキスト{追加} \ ) と組み合わせて、加算演算値の最大の増加、上にある実際の値に更新された履歴値を
ノー子ノードの場合、\(\テキスト{MOD} \ ) のマークとフラグ\(\テキスト{追加} \ ) のヒット、そうでない場合(\ \テキスト{modは}) \ 遊び。
子ノードに関連し且つに現在の動作値、更新された操作に対応する履歴値

マークをオーバーレイ分散型場合、最初の\(\テキストモッド} {\) 歴史的最大カバレッジ値)履歴と子ノードの値を更新する(\テキストモッド} {\)\
次に、実用的な最大値と実際のカバレッジ実際のオーバライド値を変更します。

割り当て後、添加の順序は、最初の点に留意する分散型マーク。分散型マーカーの少数の書き込み動作は、速度の利点が存在し得ます。

ここでは、この問題のためのコードがある、それは、2020年には1月19日ランク-1ロス・バレーです。

#include<stdio.h>
#include<algorithm>
using namespace std;

const int N = 100005;
const int inf = 1e9;

struct IO_tp
{
    static const int Sbuf=1<<21;
    char buf[Sbuf], *S, *T, c; int f;
    #define gc() (S==T?(T=(S=buf)+fread(buf,1,sizeof(buf),stdin),(S==T?EOF:*S++)):*S++)
    template<class I>
    inline IO_tp& operator >> (I &x)
    {
        for(f=1, c=gc(); c<'0'||c>'9'; c=gc()) if(c=='-') f=-1;
        for(x=0; c>='0'&&c<='9'; c=gc()) x=x*10+(c^48); x*=f;
        return *this;
    }
    inline char Readc()
    {
        for(c=gc(); c<'A'||c>'Z'; c=gc());
        return c;
    }
}io;

inline void ckmax(int&x,const int y)
{ x = x < y ? y : x; }

struct Segtree
{
    struct node {
        int max, add, mod;
        int Max, Add, Mod;
        node(): mod(-inf), Mod(-inf) {}
    }t[N << 2];
    
    #define lc (o << 1)
    #define rc (o << 1 | 1)
    
    void pushup(int o)
    {
        t[o].max = max(t[lc].max, t[rc].max);
        t[o].Max = max(t[lc].Max, t[rc].Max);
    }
    
    void dadd(int o, int x, int y)
    {
        ckmax(t[o].Max, t[o].max + x);
        t[o].max += y;
        if(t[o].mod == -inf)
            ckmax(t[o].Add, t[o].add + x), t[o].add += y;
        else
            ckmax(t[o].Mod, t[o].mod + x), t[o].mod += y;
    }
    
    void dmod(int o, int x, int y)
    {
        ckmax(t[o].Max, x);
        ckmax(t[o].Mod, x);
        t[o].mod = t[o].max = y;
    }
    
    void pushdown(int o)
    {
        if(t[o].add || t[o].Add)
        {
            dadd(lc, t[o].Add, t[o].add);
            dadd(rc, t[o].Add, t[o].add);
            t[o].Add = t[o].add = 0;
        }
        if(t[o].mod != -inf)
        {
            dmod(lc, t[o].Mod, t[o].mod);
            dmod(rc, t[o].Mod, t[o].mod);
            t[o].Mod = t[o].mod = -inf;
        }
    }
    
    void build(int o, int l, int r)
    {
        if(l == r)
        {
            int k; io >> k;
            t[o].max = t[o].Max = k;
            return;
        }
        int mid = (l + r) >> 1;
        build(lc, l, mid); build(rc, mid + 1, r);
        pushup(o);
    }
    
    void update(int o, int l, int r, int pl, int pr, int x)
    {
        if(l > pr || r < pl)
            return;
        if(l >= pl && r <= pr)
        {
            dadd(o, x, x);
            return;
        }
        pushdown(o);
        int mid = (l + r) >> 1;
        update(lc, l, mid, pl, pr, x);
        update(rc, mid + 1, r, pl, pr, x);
        pushup(o);
    }
    
    void modify(int o, int l, int r, int pl, int pr, int x)
    {
        if(l > pr || r < pl)
            return;
        if(l >= pl && r <= pr)
        {
            dmod(o, x, x);
            return;
        }
        pushdown(o);
        int mid = (l + r) >> 1;
        modify(lc, l, mid, pl, pr, x);
        modify(rc, mid + 1, r, pl, pr, x);
        pushup(o);
    }
    
    int query(int o, int l, int r, int pl, int pr)
    {
        if(l > pr || r < pl)
            return -inf;
        if(l >= pl && r <= pr)
            return t[o].max;
        pushdown(o);
        int mid = (l + r) >> 1;
        return max(query(lc, l, mid, pl, pr), query(rc, mid + 1, r, pl, pr));
    }
    
    int Query(int o, int l, int r, int pl, int pr)
    {
        if(l > pr || r < pl)
            return -inf;
        if(l >= pl && r <= pr)
            return t[o].Max;
        pushdown(o);
        int mid = (l + r) >> 1;
        return max(Query(lc, l, mid, pl, pr), Query(rc, mid + 1, r, pl, pr));
    }
}z[1];

int main()
{
    freopen("cpu.in", "r", stdin);
    freopen("cpu.out", "w", stdout);
    int n, q, l, r, x; char opt[3];
    io >> n;
    z->build(1, 1, n);
    io >> q;
    while(q--)
    {
        opt[0] = io.Readc();
        io >> l >> r;
        if(*opt == 'Q')
            printf("%d\n", z->query(1, 1, n, l, r));
        if(*opt == 'A')
            printf("%d\n", z->Query(1, 1, n, l, r));
        if(*opt == 'P')
            io >> x, z->update(1, 1, n, l, r, x);
        if(*opt == 'C')
            io >> x, z->modify(1, 1, n, l, r, x);
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/bestwyj/p/12215649.html