zoukankan      html  css  js  c++  java
  • 圆的异或并

    bzoj 4561 圆的异或并

    题意

    在平面直角坐标系中给定(N)个圆。已知这些圆两两没有交点,即两圆的关系只存在相离和包含。求这些圆的异或面
    积并。异或面积并为:当一片区域在奇数个圆内则计算其面积,当一片区域在偶数个圆内则不考虑。

    解法

    这个很简单

    因为圆两两不相交,所以其相对位置不变,所以我们将其拆为两个半圆弧,当我们碰到左端点的时候,就加入这两个圆弧,碰到右端点的时候,就将他们删去。然后我们从左到右扫描,找出当前这个圆的前驱,若他为上圆弧,则当前圆为其儿子,否则为其兄弟。这样我们就将圆变为了一个树形图,其中深度为奇数的贡献为正,否则为负。

    代码如下:

    注意:!!!!

    1. 如果set重载小于号的时候,不定义完全,会WA。我就错了几遍
    2. T一定要为当前的x,不然会WA。
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <set>
    #define INF 2139062143
    #define MAX 0x7ffffffffffffff
    #define del(a,b) memset(a,b,sizeof(a))
    #define Rint register int
    using namespace std;
    typedef long long ll;
    template<typename T>
    inline void read(T&x)
    {
        x=0;T k=1;char c=getchar();
        while(!isdigit(c)){if(c=='-')k=-1;c=getchar();}
        while(isdigit(c)){x=x*10+c-'0';c=getchar();}x*=k;
    }
    const int maxn=200000+5;
    double T;
    struct cir{
    	double x,y,r;
    	cir(double x=0.0,double y=0.0,double r=0.0):x(x),y(y),r(r){}
    	double h(int k){
    		return y + k*sqrt( r*r - (T-x)*(T-x) );
    	}
    }c[maxn];
    struct pic{
    	int num,k,deg;
    	pic(int num=0,int k=0,int deg=0):num(num),k(k),deg(deg){}
    }p[maxn<<1];
    bool operator < (const pic& a,const pic& b){
    	double y1=c[a.num].h(a.k),y2=c[b.num].h(b.k);
    	if(y1!=y2) return y1<y2;
    	return a.k<b.k;
    }
    bool cmp(pic a,pic b){
    	double x1=c[a.num].x-a.k*c[a.num].r;
    	double x2=c[b.num].x-b.k*c[b.num].r;
    	return x1<x2;
    }
    set<pic> s;
    int n;
    int main()
    {
    //	freopen("4561.in","r",stdin);
    //	freopen("4561.out","w",stdout);
    	read(n);
    	for(int i=1;i<=n;i++){
    		scanf("%lf%lf%lf",&c[i].x,&c[i].y,&c[i].r);
    		p[i*2-1]=pic(i,1);
    		p[i*2]=pic(i,-1);
    	}
    	sort(p+1,p+1+2*n,cmp);
    	set<pic>:: iterator it;
    	ll ans=0;
    	int deg;
    	for(int i=1;i<=2*n;i++){
    		T=c[p[i].num].x-p[i].k*c[p[i].num].r;//当前的扫描线位置
    		if(p[i].k==1){
    			it=s.upper_bound(p[i]);
    			if(it==s.end()) deg=1;
    			else{
    				if(it->k==1) deg=it->deg+1;
    				else deg=it->deg;
    			}
    			if(deg&1) ans+=ll(c[p[i].num].r*c[p[i].num].r);
    			else ans-=ll(c[p[i].num].r*c[p[i].num].r);
    			s.insert(pic(p[i].num,1,deg));
    			s.insert(pic(p[i].num,-1,deg));
    		}
    		else{
    			s.erase(pic(p[i].num,1,deg));
    			s.erase(pic(p[i].num,-1,deg));
    		}
    	}
    	printf("%lld",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    www.insidesql.org
    kevinekline----------------- SQLSERVER MVP
    Sys.dm_os_wait_stats Sys.dm_performance_counters
    如何使用 DBCC MEMORYSTATUS 命令来监视 SQL Server 2005 中的内存使用情况
    VITAM POST MORTEM – ANALYZING DEADLOCKED SCHEDULERS MINI DUMP FROM SQL SERVER
    Cargo, Rust’s Package Manager
    建筑识图入门(初学者 入门)
    Tracing SQL Queries in Real Time for MySQL Databases using WinDbg and Basic Assembler Knowledge
    Microsoft SQL Server R Services
    The Rambling DBA: Jonathan Kehayias
  • 原文地址:https://www.cnblogs.com/mrasd/p/9509279.html
Copyright © 2011-2022 走看看