萌新求教,卡在9分了。。。

P4513 小白逛公园

翰空之眼 @ 2019-06-02 10:37:32

/*
动态维护最大字段和:
1.此段的和(tr[now*2].sum + tr[now*2+1].sum)
2.包含左端单的此段最大字段和 max(tr[now*2].sum + tr[now*2+1].lm, tr[now*2].lm)
3.包含右端点的此段最大字段和 max(tr[now*2].rm + tr[now*2+1].sum, tr[now*2+1].rm)
4.此段最大字段和 max(max(tr[now*2].rm + tr[now*2+1].lm, tr[now*2].mx), tr[now*2+1].mx)
*/
#include <iostream>
#include <stdio.h>
#include <cmath>
using namespace std;
const int N = 5e5 + 9;
struct tree{
    int sum, lm, rm, mx, l, r;
}tr[N << 2], lans, rans, ans;
int a[N], n, m;
void together(int now){
    tr[now].sum = tr[now*2].sum + tr[now*2+1].sum;
    tr[now].lm = max(tr[now*2].sum + tr[now*2+1].lm, tr[now*2].lm);
    tr[now].rm = max(tr[now*2].rm + tr[now*2+1].sum, tr[now*2+1].rm);
    tr[now].mx = max(max(tr[now*2].rm + tr[now*2+1].lm, tr[now*2].mx), tr[now*2+1].mx);
}
void build(int now, int l, int r){
    tr[now].l = l, tr[now].r = r;
    if(l == r){
        tr[now].sum = tr[now].lm = tr[now].rm = tr[now].mx = a[l];
        return;
    }
    int mid = (l + r) / 2;
    build(2*now, l, mid); build(2*now+1, mid+1, r);
    together(now);
}
tree query(int now, int l, int r){
    int lx = tr[now].l, rx = tr[now].r;
    int mid = tr[2*now].r;
    if(lx == l && rx == r) return tr[now];
    if(r <= mid) return query(now*2, l, r);
    if(l > mid) return query(now*2+1, l, r);
    lans = query(now*2, l, mid), rans = query(now*2+1, mid+1, r);
    ans.sum = lans.sum + rans.sum;
    ans.lm = max(lans.sum + rans.lm, lans.lm);
    ans.rm = max(lans.rm + rans.sum, rans.rm);
    ans.mx = max(max(lans.rm + rans.lm, lans.mx), rans.mx);
    return ans;
}
void change(int now, int p, int d){
    int lx = tr[now].l, rx = tr[now].r;
    if(lx == rx){
        tr[now].sum = tr[now].lm = tr[now].rm = tr[now].mx = d;
        return;
    } 
    int mid = tr[2*now].r;
    change(now * 2 + (mid < p), p, d);
    together(now);
}
int main()
{
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    build(1, 1, n);
    for(int i = 1; i <= m; i++){
        int x, y, z; scanf("%d %d %d", &z, &x, &y);
        if(z == 1) {
            if(x > y) swap(x, y);
            printf("%d\n", query(1, x, y).mx);
        }
        else change(1, x, y);
    }
    return 0;
}

求大佬神仙们帮忙看看


by 翰空之眼 @ 2019-06-09 19:42:37

终于过了。。。


by YOU法克 @ 2019-07-23 17:28:53

@翰空之眼

dalao

我被卡到了九分 怎么办呀QAQ


by YOU法克 @ 2019-07-23 17:29:53

@翰空之眼

能不能稍微给我看一看 [照片]


by 翰空之眼 @ 2019-07-23 18:15:08

@YOU法克 我把我的代码给你看看吧?我是错在递归变量开成全局的了(一定要开在函数里!)


by 翰空之眼 @ 2019-07-23 18:15:55

/*
动态维护最大字段和:
1.此段的和(tr[now*2].sum + tr[now*2+1].sum)
2.包含左端单的此段最大字段和 max(tr[now*2].sum + tr[now*2+1].lm, tr[now*2].lm)
3.包含右端点的此段最大字段和 max(tr[now*2].rm + tr[now*2+1].sum, tr[now*2+1].rm)
4.此段最大字段和 max(max(tr[now*2].rm + tr[now*2+1].lm, tr[now*2].mx), tr[now*2+1].mx)
*/
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <cassert>
using namespace std;
const int N = 5e5 + 9;
struct tree{
    int sum, lm, rm, mx, l, r;
}tr[N << 3];
int a[N], n, m;
void together(int now){
    tr[now].sum = tr[now*2].sum + tr[now*2+1].sum;
    tr[now].lm = max(tr[now*2].sum + tr[now*2+1].lm, tr[now*2].lm);
    tr[now].rm = max(tr[now*2].rm + tr[now*2+1].sum, tr[now*2+1].rm);
    tr[now].mx = max(max(tr[now*2].rm + tr[now*2+1].lm, tr[now*2].mx), tr[now*2+1].mx);
}
void build(int now, int l, int r){
    tr[now].l = l, tr[now].r = r;
    if(l == r){
        tr[now].sum = tr[now].lm = tr[now].rm = tr[now].mx = a[l];
        return;
    }   
    int mid = (l + r) / 2;
    build(2*now, l, mid); build(2*now+1, mid+1, r);
    together(now);
}
tree query(int now, int l, int r){
    int lx = tr[now].l, rx = tr[now].r;
    int mid = tr[2*now].r;
    if(l <= lx && rx <= r) return tr[now];
    if(r <= mid) return query(now*2, l, r);
    if(l > mid) return query(now*2+1, l, r);
    tree lans = query(now*2, l, mid), rans = query(now*2+1, mid+1, r), ans;
    ans.sum = lans.sum + rans.sum;
    ans.lm = max(lans.sum + rans.lm, lans.lm);
    ans.rm = max(lans.rm + rans.sum, rans.rm);
    ans.mx = max(max(lans.rm + rans.lm, lans.mx), rans.mx);
    return ans;
}
void change(int now, int p, int d){
    int lx = tr[now].l, rx = tr[now].r;
    assert(lx <= p && p <= rx);
    if(lx == rx){
        tr[now].sum = tr[now].lm = tr[now].rm = tr[now].mx = d;
        return;
    } 
    int mid = tr[2*now].r;
    change(now * 2 + (mid < p), p, d);
    together(now);
}
int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    build(1, 1, n);
    for(int i = 1; i <= m; i++){
        int x, y, z; scanf("%d%d%d", &z, &x, &y);
        if(z == 1) {
            if(x > y) swap(x, y);
            printf("%d\n", query(1, x, y).mx);
        }
        else change(1, x, y);
    }
    return 0;
}

by YOU法克 @ 2019-07-23 19:22:47

@翰空之眼

我自己过了,谢谢dalao

同样感谢 Orz


|