http://acm.hdu.edu.cn/showproblem.php?pid=3255
将种子的价值看做高度,即转化成若干个长方体的体积并
枚举z轴,扫描线
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; #define N 30001 typedef long long LL; int m,p[4]; int X1[N],X2[N],Y1[N],Y2[N],s[N]; int has[N<<1],tot; struct line { int xl,xr,h,f; }e[N<<1]; int sum[N<<3],col[N<<3]; void read(int &x) { x=0; int f=1; char c=getchar(); while(!isdigit(c)) { if(c==‘-‘) f=-1; c=getchar(); } while(isdigit(c)) { x=x*10+c-‘0‘; c=getchar(); } if(f<0) x=-x; } bool cmp(line p,line q) { return p.h<q.h; } void up(int k,int l,int r) { if(col[k]) sum[k]=has[r+1]-has[l]; else if(l==r) sum[k]=0; else sum[k]=sum[k<<1]+sum[k<<1|1]; } void change(int k,int l,int r,int opl,int opr,int ty) { if(l>=opl && r<=opr) { col[k]+=ty; up(k,l,r); return; } int mid=l+r>>1; if(opl<=mid) change(k<<1,l,mid,opl,opr,ty); if(opr>mid) change(k<<1|1,mid+1,r,opl,opr,ty); up(k,l,r); } int main() { int T,n,u,d,tot,g; LL ans; read(T); for(int t=1;t<=T;++t) { read(n); read(m); for(int i=1;i<=m;++i) scanf("%d",&p[i]); tot=0; for(int i=1;i<=n;++i) { scanf("%d%d%d%d%d",&X1[i],&Y1[i],&X2[i],&Y2[i],&s[i]); has[++tot]=Y1[i]; has[++tot]=Y2[i]; s[i]=p[s[i]]; } sort(has+1,has+tot+1); tot=unique(has+1,has+tot+1)-has-1; sort(p+1,p+m+1); m=unique(p+1,p+m+1)-p-1; ans=0; for(int j=1;j<=m;++j) { g=0; for(int i=1;i<=n;++i) if(s[i]>=p[j]) { u=++g; d=++g; e[u].xl=lower_bound(has+1,has+tot+1,Y1[i])-has; e[u].xr=lower_bound(has+1,has+tot+1,Y2[i])-has-1; e[u].h=X1[i]; e[u].f=1; e[d].xl=e[u].xl; e[d].xr=e[u].xr; e[d].h=X2[i]; e[d].f=-1; } sort(e+1,e+g+1,cmp); for(int i=1;i<=g;++i) { change(1,1,tot,e[i].xl,e[i].xr,e[i].f); ans+=1LL*sum[1]*(p[j]-p[j-1])*(e[i+1].h-e[i].h); } } printf("Case %d: %lld\n",t,ans); } return 0; }
Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2188 Accepted Submission(s): 694
原文:https://www.cnblogs.com/TheRoadToTheGold/p/12203490.html