题目:http://acm.hdu.edu.cn/showproblem.php?pid=3255
题意:在一块地上种蔬菜,对于同一块地蔬菜价值高的一定是最后存活,求最后的蔬菜总值,也就是不同的矩形覆盖,有的矩
形肯定在最上面。
#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
using namespace std;
const int N = 160005;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
int cnt[N],M,v[N];
double D[N],sum[N];
struct Line
{
double l,r,h;
int s,v;
Line(){}
Line(double a,double b,double c,int d,int e):l(a),r(b),h(c),s(d),v(e){}
bool operator< (const Line &cmp)const
{
return h<cmp.h;
}
}L[N],temp[N];
int BinarySearch(double x)
{
int l,r,m;
l=1;r=M;
while(l<=r)
{
m=(l+r)>>1;
if(D[m]==x)
return m;
if(D[m]<x) l=m+1;
else r=m-1;
}
}
void Pushup(int l,int r,int rt)
{
if(cnt[rt]) sum[rt] = D[r+1] - D[l];
else if(l==r) sum[rt]=0;
else sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void Update(int x,int y,int z,int l,int r,int rt)
{
if(x<=l&&r<=y)
{
cnt[rt]+=z;
Pushup(l,r,rt);
return ;
}
int mid=(l+r)>>1;
if(x<=mid)
Update(x,y,z,lson);
if(y>mid)
Update(x,y,z,rson);
Pushup(l,r,rt);
}
int main()
{
int n,i,j,k,ca=1,l,r,m,ct,t;
double ans,lx,ly,rx,ry;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
k=0;
for(i=1;i<=m;i++)
scanf("%d",&v[i]);
for(i=1;i<=n;i++)
{
scanf("%lf%lf%lf%lf%d",&lx,&ly,&rx,&ry,&r);
D[++k]=lx;
L[k]=Line(lx,rx,ly,1,v[r]);
D[++k]=rx;
L[k]=Line(lx,rx,ry,-1,v[r]);
}
sort(D+1,D+1+k);
sort(L+1,L+1+k);
M=1;
for(i=2;i<=k;i++)
if(D[i]!=D[i-1])
D[++M]=D[i];
ans=0;
v[0]=0;
sort(v,v+m+1);
for(j=1;j<=m;j++)
{
ct=0;
for(i=1;i<=k;i++)
if(L[i].v>v[j-1])
temp[ct++]=L[i];
memset(cnt,0,sizeof(cnt));
memset(sum,0,sizeof(sum));
for(i=0;i<ct-1;i++)
{
l=BinarySearch(temp[i].l);
r=BinarySearch(temp[i].r)-1;
if(l<=r)
Update(l,r,temp[i].s,1,M,1);
ans+=sum[1]*(double)(v[j]-v[j-1])*(temp[i+1].h-temp[i].h);
}
}
printf("Case %d: %.0lf\n",ca++,ans);
}
return 0;
}