扫描线+set 10pts 求调
查看原帖
扫描线+set 10pts 求调
530180
KingPowers楼主2023/4/16 20:44

Rt,思路就是扫描线+set维护圆的包含关系,实现就参考的第一篇题解,10pts。

#include<bits/stdc++.h>
#define int long long
#define fi first
#define se second
#define Mp make_pair
#define For(i,a,b) for(int i=a;i<=b;i++)
#define Rof(i,a,b) for(int i=a;i>=b;i--)
#define sqr(x) (x*x)
using namespace std;
typedef unsigned long long ull;
typedef double db;
typedef long double ld;
typedef pair<int,int> pii;
const int N=5e5+5;
const int mod=1e9+7;
const double eps=1e-9;
int read(){
	int ans=0,flag=1;char ch=getchar();
	for(;!isdigit(ch);ch=getchar())if(ch=='-')flag=-1;
	for(;isdigit(ch);ch=getchar())ans=ans*10+(ch^48);
	return ans*flag;
}
struct circle{
	int x,y,r;
}c[N];
int n,lx,ans,d[N];
struct Node{
	int type,id;
	Node(int a=0,int b=0):type(a),id(b){}
	double get(){return c[id].y+(double)type*(sqrt(sqr(c[id].r)-sqr(lx-c[id].x))+eps);}  //求与扫描线的交点 
	friend bool operator<(Node a,Node b){return a.get()<b.get()-eps;}
};
struct line{
	int type,x,id;
	line(int a=0,int b=0,int c=0):type(a),x(b),id(c){}
	friend bool operator<(const line &a,const line &b){return a.x<b.x;}
}q[N];
set<Node>st;
signed main(){
	n=read();
	For(i,1,n){
		c[i].x=read(),c[i].y=read(),c[i].r=read();
		q[(i<<1)-1]={1,c[i].x-c[i].r,i};  //插入上下圆弧 
		q[i<<1]={-1,c[i].x+c[i].r,i};
	}
	sort(q+1,q+(n<<1)+1);
	For(i,1,(n<<1)){
		lx=q[i].x;
		if(q[i].type==1){
			set<Node>::iterator it=st.insert(Node(1,q[i].id)).fi;
			if(it==st.begin()) d[q[i].id]=1; //是最外层的 
			else{
				it--;
				d[q[i].id]=d[(*it).id]^((*it).type<0);  //判断包含/并列关系 
			}
			ans+=(d[q[i].id]?1:-1)*sqr(c[q[i].id].r);
			st.insert(Node(-1,q[i].id));
		}
		else st.erase({1,q[i].id}),st.erase({-1,q[i].id});
	}
	printf("%lld",ans);
	return 0;
}
2023/4/16 20:44
加载中...