现在的位置: 首页 > 综合 > 正文

POJ 2482:Stars in Your Window

2013年08月09日 ⁄ 综合 ⁄ 共 1870字 ⁄ 字号 评论关闭

静态二叉检索树。

其实说来奇怪,

学ACM这么长时间了,而且我还是负责基础数据结构的,

居然连这个都没写过。

//我发现我现在做的题都好水啊咋办咋办。。

题目链接:http://poj.org/problem?id=2482

题意:

给出平面上的一些点,每个点有权值

问用一个w*h的矩形最多框住的点权和是多少

矩形边框上的点不算在矩形内

算法

把每个点拆成四个点,(x,y,val),(x,y+h,-val),(x+w,y,-val),(x+w,y+h,val)

对y进行离散化

由于是每个点加入之后都查询一次最大值,

所以插入时,值为负的应当在前。也就是排序时应该按照(x,val)点对排序,而不是按照(x,y,val)三元组排序

然后用二叉检索树对于每个节点维护两个值。

对于节点rt,假设它所在的子树种最靠左的点(即y值最小的点)是l,那么

sum[rt]=sum of [l,rt]

tr[rt]=max(sum of(l,x)) x是节点rt及其两棵子树种的任意点

trick: x,y虽然是int范围,但加上w,h后就会越界。

代码如下:

#include<cstdio>
#include<iostream>
#include<sstream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<climits>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#include<stack>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define eps 1e-8
using namespace std;

const int MAXN=11000;
vector<long long>hash;
vector<pair<pair<long long, int>, long long> >node;
int tr[MAXN<<3],sum[MAXN<<3];

void update(int l, int r, int x, int c, int rt) {

    int mid=(l+r)>>1;
    if(mid==x) {
        sum[rt]+=c;
    } else if(x<mid) {
        update(l,mid-1,x,c,rt<<1);
        sum[rt]+=c;
    } else {
        update(mid+1,r,x,c,rt<<1|1);
    }
    tr[rt]=sum[rt];
    if(l<mid) {
        tr[rt]=max(tr[rt],tr[rt<<1]);
    }
    if(r>mid) {
        tr[rt]=max(tr[rt],sum[rt]+tr[rt<<1|1]);
    }
}

int main() {
    int n,w,h;
    while(scanf("%d%d%d",&n,&w,&h)==3) {
        hash.clear();
        node.clear();
        for(int i=0; i<n; i++) {
            long long x,y;
            int val;
            scanf("%lld%lld%d",&x,&y,&val);
            node.push_back(make_pair(make_pair(x,val),y));
            node.push_back(make_pair(make_pair(x+w,-val),y));
            node.push_back(make_pair(make_pair(x,-val),y+h));
            node.push_back(make_pair(make_pair(x+w,val),y+h));
            hash.push_back(y);
            hash.push_back(y+h);
        }
        sort(hash.begin(),hash.end());
        hash.erase(unique(hash.begin(),hash.end()),hash.end());
        sort(node.begin(),node.end());
        memset(tr,0,sizeof(tr));
        memset(sum,0,sizeof(sum));
        int ans=0;
        int lim=hash.size();
        for(int i=0; i<node.size(); i++) {
            update(0,lim-1,lower_bound(hash.begin(),hash.end(),node[i].second)-hash.begin(),node[i].first.second,1);
            ans=max(ans,tr[1]);
        }
        printf("%d\n",ans);
    }
    return 0;
}

抱歉!评论已关闭.