Interval history value notes - segment tree

example

CPU monitor
to your maintenance operations on the sequence:
1, range plus
2, zone assignment
3, the maximum interval
4, interval values history

+ Mark using segment tree maintenance, all events occurring on the node record.

We noticed a segment tree node, if the modify operation, then the next additions can be considered modify.

Then on a mark length of at most 2 to the node.

Set \ (\ text {add} \ ) mark to increase the actual value of the node, \ (\ MOD {text} \) denotes a cover.
Consider recording \ (\ text {Add} \ ) mark all of its ancestors \ (\ text {add} \ ) markers, the maximum achievable history. \ (\ text {Mod} \ ) Similarly.
When the note mark indicia on decentralized child node before the occurrence time point, and so time-sequentially be combined as follows:

When the addition flag decentralized, on the one hand due to the \ (\ text {Add} \ ) is above the maximum increase in the adding operation values, which in combination with the actual value is updated history value .
If no child nodes \ (\ text {mod} \ ) flag to mark that \ (\ text {add} \ ) hit, otherwise the (\ \ text {mod}) \ play on.
In connection with the child node and to the current operating values , corresponding to the updated operation history value .

When decentralized overlay marks, first with \ (\ text Mod} {\) (Historical maximum coverage value) updates the value of history and child nodes \ (\ text Mod} {\) .
Then modify the practical maximum value and the actual coverage actual override value.

Decentralized marker to be noted that the order of addition prior, after assignment. Since the writing operation of the small number of decentralized marker, there may be a speed advantage.

Here is the code for this question, it is Rank1 Los Valley in 2020, January 19.

#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;
}

Guess you like

Origin www.cnblogs.com/bestwyj/p/12215649.html