Time Limit: 2000MS | Memory Limit: 10000K | |
Total Submissions: 11643 | Accepted: 6141 |
计算几何,扫描线,看了好几天看懂一点,
推荐博客:http://www.cppblog.com/abilitytao/archive/2010/07/21/120927.html
http://www.cnblogs.com/shuaiwhu/archive/2012/04/22/2464876.html
Description
Input
Output
Sample Input
7 -15 0 5 10 -5 8 20 25 15 -4 24 14 0 -6 16 4 2 15 10 22 30 10 36 20 34 0 40 16
Sample Output
228
Source
#include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #include <stack> #include <set> using namespace std; const int N=1e4+6; struct node { int l,r; int cover; int lcover,rcover; int sum; int len; int seg; }; node ST[N<<2]; int A[N]; int n,cnt; struct Line { int x,y1,y2; int Inline; bool operator<(const Line& J)const { return x<J.x; } }; Line ILine[N]; void build(int l,int r,int rt) { ST[rt].l=l; ST[rt].r=r; ST[rt].len=A[r]-A[l]; ST[rt].lcover=ST[rt].rcover=0; ST[rt].rcover=0; ST[rt].seg=ST[rt].sum=0; if(r-l>1) { int mid=(l+r)>>1; build(l,mid,rt<<1); build(mid,r,rt<<1|1); } } void getsum(int rt) { if(ST[rt].cover>0) ST[rt].sum=ST[rt].len; else if(ST[rt].r-ST[rt].l>1) ST[rt].sum=ST[rt<<1].sum+ST[rt<<1|1].sum; else ST[rt].sum=0; } void getseg(int rt) { if(ST[rt].cover>0) { ST[rt].lcover=ST[rt].rcover=1; ST[rt].seg=1; } else if(ST[rt].r-ST[rt].l>1) { ST[rt].lcover=ST[rt<<1].lcover; ST[rt].rcover=ST[rt<<1|1].rcover; ST[rt].seg=ST[rt<<1].seg+ST[rt<<1|1].seg-ST[rt<<1].rcover*ST[rt<<1|1].lcover; } else { ST[rt].rcover=ST[rt].lcover=0; ST[rt].seg=0; } } void Insert(int l,int r,int rt) { if(l==ST[rt].l&&r==ST[rt].r) ST[rt].cover++; else { int mid=(ST[rt].l+ST[rt].r)>>1; if(l>=mid) Insert(l,r,rt<<1|1); else if(r<=mid) Insert(l,r,rt<<1); else { Insert(l,mid,rt<<1); Insert(mid,r,rt<<1|1); } } getsum(rt); getseg(rt); } void Delete(int l,int r,int rt) { if(l==ST[rt].l&&r==ST[rt].r) ST[rt].cover--; else { int mid=(ST[rt].l+ST[rt].r)>>1; if(l>=mid) Delete(l,r,rt<<1|1); else if(r<=mid) Delete(l,r,rt<<1); else { Delete(l,mid,rt<<1); Delete(mid,r,rt<<1|1); } } getsum(rt); getseg(rt); } int getx(int x) { return lower_bound(A,A+cnt,x)-A; } int main() { while(cin>>n) { cnt=0; int x1,x2,y1,y2; for(int i=0;i<n;i++) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); ILine[i<<1].x=x1; ILine[i<<1|1].x=x2; ILine[i<<1].y1=ILine[i<<1|1].y1=y1; ILine[i<<1].y2=ILine[i<<1|1].y2=y2; ILine[i<<1].Inline=1; ILine[i<<1|1].Inline=0; A[i<<1]=y1; A[i<<1|1]=y2; } n<<=1; sort(ILine,ILine+n); sort(A,A+n); for(int i=1;i<n;i++) { if(A[i]!=A[i-1]) A[cnt++]=A[i-1]; } A[cnt++]=A[n-1]; build(0,cnt-1,1); int ans=0; int lsum=0; for(int i=0;i<n-1;i++) { if(ILine[i].Inline) Insert(getx(ILine[i].y1),getx(ILine[i].y2),1); else Delete(getx(ILine[i].y1),getx(ILine[i].y2),1); ans+=ST[1].seg*(ILine[i+1].x-ILine[i].x)*2; ans+=abs(ST[1].sum-lsum); lsum=ST[1].sum; } Delete(getx(ILine[n-1].y1),getx(ILine[n-1].y2),1); ans+=abs(ST[1].sum-lsum); printf("%d\n",ans); } return 0; }