• [JLOI2016]圆的异或并


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

    Input
    第一行包含一个正整数N,代表圆的个数。接下来N行,每行3个非负整数x,y,r,表示一个圆心在(x,y),半径为r的圆。保证|x|,|y|,≤10^8,r>0,N<=200000

    Output
    仅一行一个整数,表示所有圆的异或面积并除以圆周率Pi的结果。

    Sample Input
    2
    0 0 1
    0 0 2

    Sample Output
    3


    由于圆只存在包含与相离的关系,所以我们可以用扫描线,把圆看成一对对括号

    然后判断一段区域的奇偶性,统计答案即可

    至于对括号的维护,我们可以用set维护其相对位置即可

    /*program from Wolfycz*/
    #include<set>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define Fi first
    #define Se second
    #define inf 0x7f7f7f7f
    #define sqr(x) ((x)*(x))
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline char gc(){
    	static char buf[1000000],*p1=buf,*p2=buf;
    	return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int frd(){
    	int x=0,f=1; char ch=gc();
    	for (;ch<'0'||ch>'9';ch=gc())	if (ch=='-')	f=-1;
    	for (;ch>='0'&&ch<='9';ch=gc())	x=(x<<3)+(x<<1)+ch-'0';
    	return x*f;
    }
    inline int read(){
    	int x=0,f=1; char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')	f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<3)+(x<<1)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x<0)	putchar('-'),x=-x;
    	if (x>9)	print(x/10);
    	putchar(x%10+'0');
    }
    const int N=2e5;
    const double eps=1e-8;
    double A[N+10],B[N+10],R[N+10],Nx;
    struct node{
    	int type,ID;
    	node(int _type=0,int _ID=0){type=_type,ID=_ID;}
    	void insert(int _type,int _ID){type=_type,ID=_ID;}
    	double T(){return B[ID]+(double)type*(sqrt(sqr(R[ID])-sqr(Nx-A[ID]))+eps);}
    };
    bool operator <(node a,node b){return a.T()-b.T()<-eps;}
    struct S1{
    	int type,v,ID;
    	void insert(int _type,int _v,int _ID){type=_type,v=_v,ID=_ID;}
    	bool operator <(const S1 &tis)const{return v<tis.v;}
    }opr[(N<<1)+10];//operator
    bool can[N+10];
    set<node>ST;
    int main(){
    	int n=read(),cnt=0; ll Ans=0;
    	for (int i=1;i<=n;i++){
    		scanf("%lf%lf%lf",A+i,B+i,R+i);
    		opr[++cnt].insert( 1,A[i]-R[i],i);
    		opr[++cnt].insert(-1,A[i]+R[i],i);
    	}
    	sort(opr+1,opr+1+cnt);
    	for (int i=1;i<=cnt;i++){
    		Nx=opr[i].v;
    		if (opr[i].type>0){
    			set<node>::iterator it=ST.insert(node(1,opr[i].ID)).Fi;
    			if (it==ST.begin())	can[opr[i].ID]=1;
    			else{	
    				it--;
    				can[opr[i].ID]=can[(*it).ID]^((*it).type<0);
    			}
    			Ans+=(can[opr[i].ID]?1:-1)*sqr(R[opr[i].ID]);
    			ST.insert(node(-1,opr[i].ID));
    		}else{
    			ST.erase(node( 1,opr[i].ID));
    			ST.erase(node(-1,opr[i].ID));
    		}
    	}
    	printf("%lld
    ",Ans);
    	return 0;
    }
    
  • 相关阅读:
    eclipse中的项目的JRE换成JDK
    Eclipse中maven项目的创建和运行
    git 发布命令
    vbox中虚拟ubuntu增加新的虚拟硬盘
    MyServer
    java常用的中间件
    高并发解决方案
    浅谈SpringMVC
    浅谈HIbernate
    javaweb笔记七
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/10577776.html
Copyright © 2020-2023  润新知