题目: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; }