zoukankan      html  css  js  c++  java
  • 2019 Multi-University Training Contest 7

    http://acm.hdu.edu.cn/showproblem.php?pid=6638

    偷学一波潘哥的二维离散化和线段树维护最大子段和。

    思路是枚举上下边界,但是不需要从左到右用最大子段和dp。

    用O(n)建立线段树之后,下边界在往下增长的时候,每次只会单点修改某个点的值,影响这个点的祖先。

    注意离散化减去的是数组的开头指针,而lowerbound减去的是另一个东西。

    #include<bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    #define lc o<<1
    #define rc o<<1|1
    
    const int MAXN = 2000 + 5;
    int x[MAXN], y[MAXN], w[MAXN], x2[MAXN], y2[MAXN];
    
    ll amax[MAXN << 2], sum[MAXN << 2], lmax[MAXN << 2], rmax[MAXN << 2];
    
    void pushup(int o) {
        sum[o] = sum[lc] + sum[rc];
        lmax[o] = max(lmax[lc], lmax[rc] + sum[lc]);
        rmax[o] = max(rmax[rc], rmax[lc] + sum[rc]);
        amax[o] = max(max(amax[lc], amax[rc]), rmax[lc] + lmax[rc]);
    }
    
    void build(int o, int l, int r) {
        if(l == r) {
            sum[o] = lmax[o] = rmax[o] = amax[o] = 0;
        } else {
            int m = l + r >> 1;
            build(lc, l, m);
            build(rc, m + 1, r);
            pushup(o);
        }
    }
    
    void update(int o, int l, int r, int x, int v) {
        if(l == r) {
            sum[o] += v;
            lmax[o] = rmax[o] = amax[o] = max(0ll, sum[o]);
        } else {
            int m = l + r >> 1;
            if(x <= m)
                update(lc, l, m, x, v);
            if(x >= m + 1)
                update(rc, m + 1, r, x, v);
            pushup(o);
        }
    }
    
    vector<pair<int, int> >upd[MAXN];
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in", "r", stdin);
    #endif // Yinku
        int T;
        while(~scanf("%d", &T)) {
            while(T--) {
                int n;
                scanf("%d", &n);
                for(int i = 1; i <= n; ++i) {
                    scanf("%d%d%d", &x[i], &y[i], &w[i]);
                    x2[i] = x[i], y2[i] = y[i];
                }
                sort(x2 + 1, x2 + 1 + n), sort(y2 + 1, y2 + 1 + n);
                int cn = unique(x2 + 1, x2 + 1 + n) - (x2 + 1);
                int  cm = unique(y2 + 1, y2 + 1 + n) - (y2 + 1);
                for(int i = 1; i <= cn; ++i)
                    upd[i].clear();
                for(int i = 1; i <= n; ++i) {
                    x[i] = lower_bound(x2 + 1, x2 + 1 + cn, x[i]) - x2;
                    y[i] = lower_bound(y2 + 1, y2 + 1 + cm, y[i]) - y2;
                    upd[x[i]].push_back({y[i], w[i]});
                }
                ll ans = 0;
                for(int i = 1; i <= cn; ++i) {
                    build(1, 1, cm);
                    for(int j = i; j <= cn; ++j) {
                        for(auto ui : upd[j])
                            update(1, 1, cm, ui.first, ui.second);
                        ans = max(ans, amax[1]);
                    }
                }
                printf("%lld
    ", ans);
            }
        }
    }
    
  • 相关阅读:
    C#中IPAddress转换成整型int
    没有注册类 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG))
    VB.NET或C#报错:You must hava a license to use this ActiveX control.
    c#几种随机数组和数组乱序
    C#封装的websocket协议类
    VB生成条形码(EAN-13)
    VB控件间的拖放
    VB用API模拟截屏键PrintScreen
    VB读写进程的内存
    几个VB常见又内涵的错误
  • 原文地址:https://www.cnblogs.com/Yinku/p/11317219.html
Copyright © 2011-2022 走看看