poj1151:http://poj.org/problem?id=1151
题意:求矩形面积的并
题解:扫描线加线段树
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=202;//注意这里的初始化,不能开小了,是200条边 7 int num;//记录x坐标的个数 8 struct Node{ 9 double l;//边的左端点 10 double r;//边的又端点 11 int tp;//是出度边还是入度边 12 double y;//边的纵坐标 13 bool operator <(Node a) const{//按照纵坐标给边进行排序,一个比较器 14 return y<a.y; 15 } 16 }line[2*maxn]; 17 double arr[2*maxn];//用于离散化 18 struct Edge{ 19 int left; 20 int right; 21 int flag;//标记该点是加入还是删除 22 double sum; 23 }node1[maxn*4]; 24 void build(int l,int r,int idx){//建树 25 node1[idx].left=l; 26 node1[idx].right=r; 27 if(l==r){ 28 node1[idx].flag=0; 29 node1[idx].sum=0; 30 return; 31 } 32 int mid=(l+r)/2; 33 build(l,mid,idx<<1); 34 build(mid+1,r,idx<<1|1); 35 node1[idx].sum=node1[idx<<1].sum+node1[idx<<1|1].sum; 36 } 37 void update(int l,int r,int f,int idx){//更新 38 if(node1[idx].left==node1[idx].right){ 39 node1[idx].flag+=f; 40 if(node1[idx].flag)node1[idx].sum=arr[node1[idx].right+1]-arr[node1[idx].left];//注意这里的家一操作 41 if(!node1[idx].flag)node1[idx].sum=0; 42 return ; 43 } 44 int mid=(node1[idx].left+node1[idx].right)/2; 45 if(mid>=r)update(l,r,f,idx<<1); 46 else if(mid<l)update(l,r,f,idx<<1|1); 47 else{ 48 update(l,mid,f,idx<<1); 49 update(mid+1,r,f,idx<<1|1); 50 } 51 node1[idx].sum=node1[idx<<1].sum+node1[idx<<1|1].sum;//pushup上去 52 } 53 int binaryserach(double x){//二分查找,也可以写成递归的形是 54 int l,r,mid; 55 l=0,r=num+1; 56 while (r-l>1){ 57 mid=(l+r)>>1; 58 if (arr[mid]<=x) l=mid; 59 else r=mid; 60 } 61 return l; 62 } 63 int main(){ 64 int n;double x1,y1,x2,y2,ans; 65 int t=1; 66 while(~scanf("%d",&n)&&n){ 67 num=0; 68 for(int i=1;i<=n;i++){ 69 scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); 70 line[2*i-1].l=x1;line[2*i-1].r=x2;line[2*i-1].y=y1;line[2*i-1].tp=1; 71 line[2*i].l=x1;line[2*i].r=x2;line[2*i].y=y2;line[2*i].tp=-1; 72 arr[++num]=x1;arr[++num]=x2;//离散化 73 } 74 sort(arr+1,arr+num+1);//排序 75 n*=2;ans=0; 76 sort(line+1,line+n+1); 77 build(1,n,1); 78 for(int i=1;i<=n;i++){ 79 ans+=node1[1].sum*(line[i].y-line[i-1].y); 80 int l=binaryserach(line[i].l); 81 int r=binaryserach(line[i].r)-1;//注意这里是要得到区间,不是单个的点,所以要加1 82 update(l,r,line[i].tp,1); 83 } 84 printf("Test case #%d ",t++); 85 printf("Total explored area: %.2f ",ans); 86 } 87 }