HDU 3255 Farming

来源:互联网 发布:windows gcc搭建 编辑:程序博客网 时间:2024/05/22 12:19

HDU 3255 Farming

线段树,扫描线

题意

二维坐标的田地,在上面按矩形区域种植。有可能一个格子种了多种作物,那么按价值最大的算。求总价值。
实际就是求立方体体积并。把作物价值想成高度。

思路

按价值离散化,一层层求。每次将价值大于当前考虑价值的边加入边表,在编表里面跑矩形面积并,乘个高度即可。

代码

#include<cstdio>#include<cstring>#include<algorithm>#define M(a,b) memset(a,b,sizeof(a))#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1using namespace std;const int MAXN=30007;typedef long long LL;struct Line{    int l, r;    int h, z;    int fl;    Line() {}    Line(int a, int b, int c, int d, int e) { l=a, r=b, h=c, z=d, fl=e; }    bool operator < (const Line &l)const    {        return h<l.h;    }}line[MAXN<<1], tline[MAXN<<1];//边表与当前考虑的边表int hax[MAXN<<1], ps[5];//hax表示x的哈希,ps表示价值struct Stree{    int cov, lenth;}stree[MAXN<<3];void pushup(int l, int r, int rt){    if(stree[rt].cov)        stree[rt].lenth=hax[r+1]-hax[l];    else if(l==r)        stree[rt].lenth=0;    else stree[rt].lenth=stree[rt<<1].lenth+stree[rt<<1|1].lenth;}void update(int L, int R, int c, int l, int r, int rt){    if(L<=l&&r<=R)    {        stree[rt].cov+=c;        pushup(l, r, rt);        return;    }    int mid=(l+r)>>1;    if(L<=mid) update(L, R, c, lson);    if(mid<R) update(L, R, c, rson);    pushup(l, r, rt);}void build(int l, int r, int rt) { M(stree, 0); }int main(){    int T;scanf("%d", &T);int cas=0;    while(T--)    {        int n, m;scanf("%d%d", &n, &m);        for(int i=1;i<=m;i++)            scanf("%d", &ps[i]);        int lam=0;        for(int i=1;i<=n;i++)        {            int a, b, c, d, e;scanf("%d%d%d%d%d", &a, &b, &c, &d, &e);            line[++lam]=Line(a, c, b, ps[e], 1);hax[lam]=a;            line[++lam]=Line(a, c, d, ps[e], -1);hax[lam]=c;        }        sort(line+1, line+1+lam);        sort(hax+1, hax+1+lam);        int k=unique(hax+1, hax+lam+1)-hax-2;        ps[0]=0;sort(ps+1, ps+m+1);        LL res=0;int cnt=0;        for(int i=1;i<=m;i++)//按价值分层考虑        {            cnt=0;            for(int j=1;j<=lam;j++)            {                if(line[j].z>ps[i-1])                    tline[++cnt]=line[j];            }            build(1, k, 1);            for(int j=1;j<=cnt;j++)            {                int l=lower_bound(hax+1, hax+k+2, tline[j].l)-hax;                int r=lower_bound(hax+1, hax+k+2, tline[j].r)-hax-1;                update(l, r, tline[j].fl, 1, k, 1);                if(j!=cnt) res+=(LL)stree[1].lenth*(ps[i]-ps[i-1])*(tline[j+1].h-tline[j].h);            }        }        printf("Case %d: %lld\n", ++cas, res);    }    return 0;}
原创粉丝点击