首页 > 代码库 > 最大字段和--GSS1 MUSHROOM ORZ

最大字段和--GSS1 MUSHROOM ORZ

过于naive了= =作为一个知识点总结一下算了。主要就是合并。对于一个区间的最大字段和,可以分别事下面的两个区间的子段和,或者事左边的右边加右边的左边。然后搞一下 = =

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;typedef long long ll;const ll maxn = 3000100;ll lson[maxn], rson[maxn], lm[maxn], rm[maxn], mans[maxn], sum[maxn];ll ne = 0, root;ll build(ll l, ll r) {    ll now = ++ ne;    if(l ^ r) {        ll mid = (l + r) >> 1;        lson[now] = build(l, mid);        rson[now] = build(mid + 1, r);    }    return now;}void update(ll now) {    if(lson[now]) {        sum[now] = sum[lson[now]] + sum[rson[now]];        lm[now] = max(lm[lson[now]], sum[lson[now]] + lm[rson[now]]);        rm[now] = max(rm[rson[now]], sum[rson[now]] + rm[lson[now]]);        mans[now] = max(max(mans[lson[now]], mans[rson[now]]), lm[rson[now]] + rm[lson[now]]);    }}void insert(ll now, ll l, ll r, ll v, ll pos) {    if(l == r) {        sum[now] = lm[now] = rm[now] = mans[now] = v;    }    else {        ll mid = (l + r) >> 1;        if(pos <= mid) insert(lson[now], l, mid, v, pos);        else insert(rson[now], mid + 1, r, v, pos);        update(now);    }}ll ask(ll now, ll l, ll r, ll ls, ll rs) {    ll ret;    if(l == ls && r == rs) ret = now;    else {        ll mid = (l + r) >> 1;        if(rs <= mid) ret = ask(lson[now], l, mid ,ls, rs);        else if(ls >= mid + 1) ret = ask(rson[now], mid + 1, r, ls, rs);        else {            ret = ++ ne;            ll rl = ask(lson[now], l, mid, ls, mid);            ll rr = ask(rson[now], mid + 1, r, mid + 1, rs);            lson[ret] = rl, rson[ret] = rr;            update(ret);        }    }    return ret;}ll ll_get() {    ll x = 0; char c = (char)getchar(); bool flag = 0;    while(!isdigit(c) && c != -) c = (char)getchar();    if(c == -) flag = 1;    while(!isdigit(c)) c = (char)getchar();    while(isdigit(c)) {        x = x * 10 + (ll)(c - 0);        c = (char)getchar();    }    if(flag) x = -x;    return x;}ll n, m;void sov() {    n = ll_get(); root = build(1, n);    for(ll i = 1; i <= n; ++ i) {        ll a = ll_get();        insert(root, 1, n, a, i);    }    m = ll_get();    while(m --) {        ll ls, rs; ls = ll_get(), rs = ll_get();        ll ans = ask(root, 1, n, ls, rs);        printf("%lld\n", mans[ans]);    }}int main() {    //freopen("test.in", "r", stdin);    //freopen("b.out", "w", stdout);    sov();    return 0;}

 

最大字段和--GSS1 MUSHROOM ORZ