zoukankan      html  css  js  c++  java
  • 《算法竞赛进阶指南》0x43线段树 扫描线算法 POJ2482

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

    给出每个点框定的区域,求区域叠加的最大值,可以通过如下算法:

    将每个可行点都标记,记录这些点上的权值,维护一个叶结点是一个权值点的线段树,更新的时候注意,由于所有的点都是可行点,所以右边界要在最后删除,遇到同样的x坐标的,优先叠加左边界的权值,然后去除结束矩形的权值。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn = 10010;
    struct node{
        int l,r;
        int ans,add;
    }t[maxn<<3];
    struct P{
        unsigned int x,y1,y2;
        int c;
        bool operator < (const P& a)const {
            return x<a.x || (x==a.x && c>a.c);
        }
    }a[maxn<<1];
    unsigned int  b[maxn<<1];
    int n;
    int num;
    unsigned int w,h;
    void build(int rt,int l,int r){
        t[rt].l=l;
        t[rt].r=r;
        t[rt].add=0;
        t[rt].ans=0;
        if(l==r)return ;
        int mid=l+r>>1;
        build(rt<<1,l,mid);
        build(rt<<1|1,mid+1,r);
    }
    void pushdown(int rt){
        if(t[rt].add){
            t[rt<<1].add+=t[rt].add;
            t[rt<<1|1].add+=t[rt].add;
            t[rt<<1].ans+=t[rt].add;
            t[rt<<1|1].ans+=t[rt].add;
            t[rt].add=0;
        }
        return ;
    }
    void update(int rt,int L,int R,int C){
        if(L<=t[rt].l && t[rt].r<=R){
            t[rt].ans+=C;
            t[rt].add+=C;
            return ;
        }
        pushdown(rt);
        int mid=(t[rt].l+t[rt].r)>>1;
        if(L<=mid)update(rt<<1,L,R,C);
        if(R>mid)update(rt<<1|1,L,R,C);
        t[rt].ans=max(t[rt<<1].ans,t[rt<<1|1].ans);
    }
    int get(unsigned int x){
        return lower_bound(b+1,b+num+1,x)-b;
    }
    void solve(){
        unsigned int x,y;
        int c;
        for(int i=1;i<=n;i++){
            int k=i<<1;
            scanf("%u%u%d",&x,&y,&c);
            a[k-1].x=x,a[k-1].y1=y,a[k-1].y2=y+h-1,a[k-1].c=c;
            a[k].x=x+w-1,a[k].y1=y,a[k].y2=y+h-1,a[k].c=-c;
            b[k-1]=y;
            b[k]=y+h-1;
        }
        sort(b+1,b+2*n+1);
        num=unique(b+1,b+2*n+1)-(b+1);
        sort(a+1,a+2*n+1);
        build(1,1,num);
        int ans=0;
        for(int i=1;i<=2*n;i++){
            int y1=get(a[i].y1);
            int y2=get(a[i].y2);
            update(1,y1,y2,a[i].c);    
            ans=max(ans,t[1].ans);//t[1]中保存了扫描段中的最大值    
        }
        cout<<ans<<endl;
    }
    int main(){
        while(cin>>n>>w>>h)solve();
        return 0;
    }
  • 相关阅读:
    Oracle资源管理器介绍(一)
    Pfile VS Spfile (MOS Note 249664.1)
    shell不能执行su 后的脚本
    Oracle 11g 新特性之Highly Available IP(HAIP)
    Oracle 11g新特性延迟段创建和truncate的增强
    Oracle 11g RAC停止和启动步骤
    测试Oracle 11gr2 RAC 非归档模式下,offline drop数据文件后的数据库的停止与启动测试全过程
    3.OGG函数
    4.3 高级特性(3) -- 过滤
    4.2 高级特性(2) -加密
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13304355.html
Copyright © 2011-2022 走看看