zoukankan      html  css  js  c++  java
  • POJ1389 Area of Simple Polygons 线段树

    POJ1389 给定n个整数点矩形,求面积并。

    显然ans必然是整数。

    记录若干个事件,每个矩形的左边的竖边记为开始,右边的竖边记为结束。

    进行坐标离散化后用线段树维护每个竖的区间, 就可以快速积分了。

    #include<stdio.h>
    #include<stdlib.h>
    #include<cstring>
    #include<math.h>
    #include<algorithm>
    #include<vector>
    using namespace std;
    
    const int maxn=100005;
    struct Rectangle
    {
     int x1,y1,x2,y2;	
    };
    
    struct Event
    {
     int x,y1,y2,add;	
    };
    
    struct IntervalTreeNode
    {
     int count,total;	
    };
    
    int n;
    
    Rectangle rect[maxn];
    Event evt[maxn<<1];
    IntervalTreeNode tree[(maxn+10)<<2];
    int id[maxn<<1];
    bool cmp(const Event &a,const Event &b)
    {
     if(a.x<b.x)return true;
     	return false;
    }
    
    void up(int i,int lb,int rb)
    {
     tree[i].total=tree[i<<1].total+tree[(i<<1)+1].total;
     if(tree[i].count)tree[i].total=id[rb]-id[lb];
    }
    
    void ins(int i,int lb,int rb,int a,int b,int k)
    {
     if(a==lb&&b==rb){
     	tree[i].count+=k;
     	up(i,lb,rb);
     	return ;
     }
     int med=(lb+rb)>>1;
     if(b<=med) ins(i<<1,lb,med,a,b,k);
     	else if(a>=med)ins((i<<1)+1,med,rb,a,b,k);
     		else{
     			 ins(i<<1,lb,med,a,med,k);
     			 ins((i<<1)+1,med,rb,med,b,k);
    		 }
     up(i,lb,rb);
    }
    
    long long area()
    {
     for(int i=0;i<n;i++){
     	id[i]=rect[i].y1;
     	id[i+n]=rect[i].y2;
     }
     sort(id,id+2*n);
     for(int i=0;i<2*n;i++){
     	rect[i].y1=lower_bound(id,id+2*n,rect[i].y1)-id;
     	rect[i].y2=lower_bound(id,id+2*n,rect[i].y2)-id;//坐标离散化 
     }
     for(int i=0;i<n;i++){
     	evt[i].add=1;
     	evt[i+n].add=-1;
     	evt[i].x=rect[i].x1;
     	evt[i+n].x=rect[i].x2;
     	evt[i].y1=evt[i+n].y1=rect[i].y1;
     	evt[i].y2=evt[i+n].y2=rect[i].y2;
     }
     sort(evt,evt+n*2,cmp);
     long long int ans=0;
     for(int i=0;i<2*n;i++){
     	if(i>0&&evt[i].x>evt[i-1].x){
     		ans+=(long long )(evt[i].x-evt[i-1].x)*tree[1].total;
    	 }
    	ins(1,0,2*n-1,evt[i].y1,evt[i].y2,evt[i].add);
     }
     return ans;
    }
    
    int main()
    {freopen("t.txt","r",stdin);
     while(true)
     {
     	n=0;
     	scanf("%d%d%d%d",&rect[0].x1,&rect[0].y1,&rect[0].x2,&rect[0].y2);
     	if(rect[0].x1==-1)return -1;
     	while(++n)
     		{
     		 scanf("%d%d%d%d",&rect[n].x1,&rect[n].y1,&rect[n].x2,&rect[n].y2);
     		 if(rect[n].x1==-1)break;
    		}
    	printf("%I64d
    ",area());
     }
     return 0;
    }
    

      

  • 相关阅读:
    [cf553C]Love Triangles
    Unix目录结构的来历
    debian学习笔记9, putty连接debian的字体乱码修改设置。
    【转】Dictionary排序
    debian学习笔记9, putty连接debian的字体乱码修改设置。
    【转】可以用圆形的钻头钻出方孔吗
    【转】Dictionary排序
    关于设置sftp 指定端口
    【转】可以用圆形的钻头钻出方孔吗
    Unix目录结构的来历
  • 原文地址:https://www.cnblogs.com/heisenberg-/p/6910124.html
Copyright © 2011-2022 走看看