codevs3044(扫描线学习)
Posted gaojunonly1
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codevs3044(扫描线学习)相关的知识,希望对你有一定的参考价值。
大意:给出n个矩形求覆盖的总面积
看了hzwer的blog 似懂非懂 链接
可能还要多练点吧qaq
#include <bits/stdc++.h> using namespace std; #define N 10005 int n,m; struct node{double x1,x2,y; int op;}line[N]; inline bool cmp(node a,node b){return a.y < b.y;} double hash[N]; struct SegmentTree{int l,r,co; double sum;}Tree[N<<2]; inline void pushup(int x) { int l=Tree[x].l,r=Tree[x].r; if(Tree[x].co>0)Tree[x].sum=hash[r+1]-hash[l]; else if(l==r) Tree[x].sum=0; else Tree[x].sum=Tree[x<<1].sum+Tree[x<<1|1].sum; } inline void build(int l,int r,int x) { Tree[x].l=l; Tree[x].r=r; Tree[x].co=0; if(l==r){Tree[x].sum=0;return;} int mid=(l+r)>>1; build(l,mid,x<<1); build(mid+1,r,x<<1|1); pushup(x); } inline void updata(int l,int r,int x,int val) { if(l<=Tree[x].l&&Tree[x].r<=r){ Tree[x].co+=val; pushup(x); return;} int mid=(Tree[x].l+Tree[x].r)>>1; if(l<=mid) updata(l,r,x<<1,val); if(r>mid) updata(l,r,x<<1|1,val); pushup(x); } int main() { while(~scanf("%d",&n)) { int i; double x1,y1,x2,y2,ans=0; if(n==0) break; for(i=1;i<=n;i++) { scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); line[i*2-1].x1=line[i*2].x1=x1; line[i*2-1].x2=line[i*2].x2=x2; line[i*2-1].y=y1; line[i*2-1].op=-1; line[i*2].y=y2; line[i*2].op=1; hash[i*2-1]=x1; hash[i*2]=x2; } n*=2; sort(line+1,line+n+1,cmp); sort(hash+1,hash+n+1); m=unique(hash+1,hash+n+1)-hash-1; build(1,m,1); for(i=n;i>=1;i--) { int l=lower_bound(hash+1,hash+m+1,line[i].x1)-hash,r=lower_bound(hash+1,hash+m+1,line[i].x2)-hash-1; updata(l,r,1,line[i].op); ans+=(line[i].y-line[i-1].y)*Tree[1].sum; } printf("%.2lf ",ans); } }
以上是关于codevs3044(扫描线学习)的主要内容,如果未能解决你的问题,请参考以下文章