您的位置:首页 > 其它

BZOJ4561 [JLoi2016]圆的异或并

2016-05-12 18:35 691 查看
这题现场的时候n=30000部分分居然是给暴力的,我分段写的个乱搞40分结果暴力都60分,差评

正解:

首先可知一个圆被奇数个圆套则答案减去其面积,被偶数个套则加上其面积,然后我们维护一个垂直于x轴扫描线,从左向右扫,每个圆拆成加入和删除两个事件,由于圆和圆不相交,所以一个圆可以看成一个括号,整个扫描线上是一个括号序列,而且随扫描线当前x增加括号之间相对顺序不变(扫描线都是某些相对顺序不变,然后维护当前x?)

因为圆和圆不相交,所以加入和删除的时候肯定都是对最内层的括号操作,只会影响到自己,所以我们只需要对扫描线上每个点记录他属于哪个圆(算出当前x下y坐标),是左括号还是右括号和外边套了几层(在新加入括号的时候用这两个算出新加的括号是第几层),然后在加入一对括号的时候查询他外面套了几层更新答案即可

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
using namespace std;
#define MAXN 200010
#define MAXM 1010
#define ll long long
#define INF 1000000000
#define MOD 1000000007
#define eps 1e-8
double nowx;
int X[MAXN],Y[MAXN],R[MAXN];
struct cir{
bool ud;
int bel;
int c;
cir(){

}
cir(int _ud,int _bel,int _c=0){
ud=_ud;
bel=_bel;
c=_c;
}
inline double y(int x){
double re=Y[bel];
if(ud){
re+=sqrt(1.0*R[bel]*R[bel]-1.0*(x-X[bel])*(x-X[bel]));
}else{
re-=sqrt(1.0*R[bel]*R[bel]-1.0*(x-X[bel])*(x-X[bel]));
}
return re;
}
friend bool operator <(cir x,cir y){
return fabs(x.y(nowx)-y.y(nowx))>eps?x.y(nowx)>y.y(nowx):x.ud>y.ud;
}
};
struct evt{
int x;
int v;
friend bool operator <(evt x,evt y){
return x.x<y.x;
}
};
int n;
set<cir>wzh;
evt e[MAXN*2];
int tot;
ll ans;
int main(){
int i;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d%d%d",&X[i],&Y[i],&R[i]);
e[++tot].x=X[i]-R[i];
e[tot].v=i;
e[++tot].x=X[i]+R[i];
e[tot].v=-i;
}
R[0]=INF;
nowx=-INF;
wzh.insert(cir(1,0,-1));
wzh.insert(cir(0,0,-1));
sort(e+1,e+tot+1);
int c;
for(i=1;i<=tot;i++){
nowx=e[i].x;
if(e[i].v>0){
cir t=*wzh.upper_bound(cir(0,e[i].v));
if(t.ud){
c=t.c;
}else{
c=t.c+1;
}
if(c&1){
ans-=(ll)R[e[i].v]*R[e[i].v];
}else{
ans+=(ll)R[e[i].v]*R[e[i].v];
}
wzh.insert(cir(1,e[i].v,c));
wzh.insert(cir(0,e[i].v,c));

}else{
e[i].v=-e[i].v;
wzh.erase(cir(1,e[i].v,c));
wzh.erase(cir(0,e[i].v,c));
}
}
printf("%lld\n",ans);
return 0;
}

/*

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: