[cf 1136] E. Nastya Hasn't Written a Legend

Posted psimonw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[cf 1136] E. Nastya Hasn't Written a Legend相关的知识,希望对你有一定的参考价值。

题意

给两个数组分别为(a)(k),有若干次操作:

1.给(a_x)加上(y),并以此对(a_{x + i}(i ge 1))赋值为(max {a_{x + i}, a_{x + i - 1} + k_{x + i - 1}})

2.询问区间([l, r])(a_i)的和。

题解

自闭了啊。

考虑把原序列分成若干个块,对于每个块内必须满足,除最后一个位置的所有位置(i)(a_i + k_i = a_i + 1)。刚开始可以看成有(n)个块。

每次修改的时候,直接对每个块内用线段树修改,块与块之间可能有合并(最多合并(O(n + q))次),然后每一次修改可能会产生(O(1))个新的块。所有块用一个set维护一下。所以总复杂度是(O((n + q) log n))的。

#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
using namespace std;
typedef long long ll;
typedef pair <int, int> pii;
 
inline int read () {
    static int x;
    scanf("%d", &x);
    return x;
}
const int N = 1e5 + 5, inf = 2e9;
int n, q, a[N], k[N]; ll pres[N];
set <pii> block;
ll s[N << 2], tag[N << 2];
#define mid ((l + r) >> 1)
#define lc (o << 1)
#define rc (o << 1 | 1)
#define ls lc, l, mid
#define rs rc, mid + 1, r
inline void pushdown (int o, int l, int r) {
    s[lc] += tag[o] * (mid - l + 1), tag[lc] += tag[o];
    s[rc] += tag[o] * (r - mid), tag[rc] += tag[o];
    tag[o] = 0;
}
inline void build (int o, int l, int r) {
    if (l == r) {s[o] = a[l]; return;}
    build(ls), build(rs);
    s[o] = s[lc] + s[rc];
}
inline void modify (int o, int l, int r, int x, int y, ll v) {
    if (x <= l && r <= y) {s[o] += v * (r - l + 1), tag[o] += v; return;}
    if (tag[o]) pushdown(o, l, r);
    if (x <= mid) modify(ls, x, y, v);
    if (y > mid) modify(rs, x, y, v);
    s[o] = s[lc] + s[rc];
}
inline ll query (int o, int l, int r, int x, int y) {
    if (x <= l && r <= y) return s[o];
    if (tag[o]) pushdown(o, l, r);
    ll ret = 0;
    if (x <= mid) ret += query(ls, x, y);
    if (y > mid) ret += query(rs, x, y);
    return ret;
}

void alter (int x, int v) {
    set <pii> :: iterator b; int l, r;
    b = block.lower_bound(mp(x, inf)), --b;
    l = b->fi, r = b->se;
    block.erase(b);
    if (l < x) block.insert(mp(l, x - 1));
    modify(1, 1, n, x, r, v);
    for ( ; r < n; ) {
        ll s = query(1, 1, n, r, r), t = query(1, 1, n, r + 1, r + 1), delta = s + k[r] - t;
        if (delta < 0) break;
        b = block.lower_bound(mp(r + 1, r + 1));
        l = b->fi, r = b->se;
        block.erase(b);
        modify(1, 1, n, l, r, delta);
    }
    block.insert(mp(x, r));
}
int main() {
    n = read();
    for (int i = 1; i <= n; ++i)
        a[i] = read(), pres[i] = pres[i - 1] + a[i];
    for (int i = 1; i < n; ++i) k[i] = read();
    for (int i = 1; i <= n; ++i) block.insert(mp(i, i));
    build(1, 1, n); 
    char op[5]; int x, y;
    for (int _ = read(); _; --_) {
        scanf("%s", op), x = read(), y = read();
        if (op[0] == '+') alter(x, y); else
        printf("%lld
", query(1, 1, n, x, y));
    }
    return 0;
}

以上是关于[cf 1136] E. Nastya Hasn't Written a Legend的主要内容,如果未能解决你的问题,请参考以下文章

codeforces 1136E-Nastya Hasn't Written a Legend

Codeforces 1136E Nastya Hasn't Written a Legend (线段树教做人系列)

[CF1136D] Nastya Is Buying Lunch - 贪心

CF1136D Nastya Is Buying Lunch 贪心

Nastya Hasn't Written a Legend(Codeforces Round #546 (Div. 2)E+线段树)

Codeforces 992 E. Nastya and King-Shamans