其他分享
首页 > 其他分享> > 2019HDU多校 Round6

2019HDU多校 Round6

作者:互联网

Solved:2

 

05 Snowy Smile (线段树)

题意:2000个物品 在坐标上 权值有正有负 求一个矩阵框起来能获得最大价值

题解:离散化坐标后 按x从小到大排序 这样枚举矩阵的左边界 依次按x往这个矩阵添物品 那么右边界也出来了

   然后在这个左右区间内 用线段树维护纵坐标的最大连续子段和 每次添加完相同横坐标的物品 查询一次

   然后傻傻的我 每次查询按这个左右区间来查询... 查询次数过多 妥妥爆栈了 其实按我的写法 每次更新后.. 不用查询 直接就是根节点的全局答案了

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 2005;
int n;
int totx, toty;

struct chest {
    int x, y, w;
    int tx, ty;
}a[2005];

bool cmp1(chest A, chest B) {
    return A.x < B.x;
}

bool cmp2(chest A, chest B) {
    return A.y < B.y;
}

struct node {
    ll sum, ssum, ls, rs;
}E[MAXN << 2];

void pushup(int rt) {
    int lr = rt << 1;
    int rr = rt << 1 | 1;
    E[rt].ssum = E[lr].ssum + E[rr].ssum;
    E[rt].sum = max(E[lr].sum, E[rr].sum);
    E[rt].sum = max(E[rt].sum, E[lr].rs + E[rr].ls);
    E[rt].ls = max(E[lr].ls, E[lr].ssum + E[rr].ls);
    E[rt].rs = max(E[rr].rs, E[rr].ssum + E[lr].rs);
}

void build(int l, int r, int rt) {
    if(l == r) {
        E[rt].sum = E[rt].ssum = E[rt].ls = E[rt].rs = 0;
        return;
    }

    int mid = l + r >> 1;
    build(l, mid, rt << 1);
    build(mid + 1, r, rt << 1 | 1);
    pushup(rt);
}

void update(int k, ll v, int l, int r, int rt) {
    if(l == r) {
        E[rt].ssum += v;
        E[rt].sum += v;
        E[rt].ls += v;
        E[rt].rs += v;
        return;
    }

    int mid = l + r >> 1;
    if(k <= mid) update(k, v, l, mid, rt << 1);
    else update(k, v, mid + 1, r, rt << 1 | 1);
    pushup(rt);
}

int main() {
    int T;
    scanf("%d", &T);
    while(T--) {
        totx = toty = 0;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].w);
        sort(a + 1, a + 1 + n, cmp2);
        for(int i = 1; i <= n; i++) {
            if(a[i].y != a[i - 1].y) a[i].ty = ++toty;
            else a[i].ty = toty;
        }
        sort(a + 1, a + 1 + n, cmp1);
        for(int i = 1; i <= n; i++) {
            if(a[i].x != a[i - 1].x) a[i].tx = ++totx;
            else a[i].tx = totx;
        }

        ll ans = 0;
        int las = -1;
        for(int i = 1; i <= n; i++) {
            if(a[i].tx == las) continue;
            build(1, toty, 1);
            int k;
            for(int j = i; j <= n; j = k) {
                for(k = j; k <= n && a[k].tx == a[j].tx; k++) update(a[k].ty, a[k].w, 1, toty, 1);
                ans = max(ans, E[1].sum);
            }
            las = a[i].tx;
        }
        printf("%lld\n", ans);
    }
    return 0;
}
Snowy Smile

 

   

标签:int,ll,矩阵,多校,查询,chest,2019HDU,Round6,Smile
来源: https://www.cnblogs.com/lwqq3/p/11324054.html