当前位置 博文首页 > ttoobne:杭电多校第六场 E Snowy Smile (线段树维护二维最大子

    ttoobne:杭电多校第六场 E Snowy Smile (线段树维护二维最大子

    作者:[db:作者] 时间:2021-08-30 10:35

    题目链接

    题解:

    枚举上下边界,用线段树维护区间最大子段和。

    具体的,首先枚举下界,固定下界的情况下,上界的枚举与计算答案并更新可以 O(n) 完成。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    typedef unsigned long long ull;
    #define int ll
    #define PI acos(-1.0)
    #define INF 0x3f3f3f3f3f3f3f3f
    #define P pair<int, int>
    #define fastio ios::sync_with_stdio(false), cin.tie(0)
    const int mod = 998244353;
    const int M = 1000000 + 10;
    const int N = 2000 + 10;
    
    int t, n;
    int ma[N<<2], lma[N<<2], rma[N<<2], sum[N<<2];
    struct node {
        int x, y, w;
        bool operator < (const node &cmp) const {
            return y < cmp.y;
        }
    } no[N];
    int cpx[N], cntx, cpy[N], cnty;
    
    void build(int l = 1, int r = cntx, int rt = 1)
    {
        ma[rt] = lma[rt] = rma[rt] = sum[rt] = 0;
        if(l == r) return ;
    
        int mid = (l + r) >> 1;
        build(l, mid, rt << 1);
        build(mid + 1, r, rt << 1 | 1);
    
    }
    
    void add(int pos, int val, int l = 1, int r = cntx, int rt = 1)
    {
        if(l == r) {
            sum[rt] += val;
            ma[rt] += val;
            lma[rt] += val;
            rma[rt] += val;
            return ;
        }
    
        int mid = (l + r) >> 1;
        if(pos <= mid) add(pos, val, l, mid, rt << 1);
        else add(pos, val, mid + 1, r, rt << 1 | 1);
    
        lma[rt] = max(lma[rt << 1], sum[rt << 1] + lma[rt << 1 | 1]);
        rma[rt] = max(rma[rt << 1 | 1], sum[rt << 1 | 1] + rma[rt << 1]);
        ma[rt] = max(max(ma[rt << 1], ma[rt << 1 | 1]), rma[rt << 1] + lma[rt << 1 | 1]);
        sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
    }
    
    signed main()
    {
        fastio;
        cin >> t;
        while(t --) {
            cin >> n;
            for(int i = 1; i <= n; i ++) {
                cin >> no[i].x >> no[i].y >> no[i].w;
                cpx[i] = no[i].x, cpy[i] = no[i].y;
            }
    
            sort(cpx + 1, cpx + 1 + n);
            cntx = unique(cpx + 1, cpx + 1 + n) - cpx - 1;
            sort(cpy + 1, cpy + 1 + n);
            cnty = unique(cpy + 1, cpy + 1 + n) - cpy - 1;
    
            for(int i = 1; i <= n; i ++) {
                no[i].x = lower_bound(cpx + 1, cpx + 1 + cntx, no[i].x) - cpx;
                no[i].y = lower_bound(cpy + 1, cpy + 1 + cnty, no[i].y) - cpy;
            }
    
            sort(no + 1, no + 1 + n);
    
            int ans = 0;
            for(int i = 1; i <= cnty; i ++) {
                build();
                int now = 1;
                while(now <= n && no[now].y < i) now ++;
                for(int j = i; j <= cnty; j ++) {
                    while(now <= n && no[now].y == j) {
                        add(no[now].x, no[now].w);
                        now ++;
                    }
                    ans = max(ans, ma[1]);
                }
            }
            cout << ans << endl;
        }
        return 0;
    }
    
    /*
    
      Rejoicing in hope, patient in tribulation.
    
    */
    

    ?

    cs
    下一篇:没有了