bzoj4561: [JLoi2016]圆的异或并
https://www.lydsy.com/JudgeOnline/problem.php?id=4561
hdu3511 变式 https://www.cnblogs.com/TheRoadToTheGold/p/12209904.html
层次为奇数的加,偶数的减
#include<set> #include<cmath> #include<cstdio> #include<iostream> #include<algorithm> using namespace std; #define N 200001 int line; struct Line { int id,xi; }e[N<<1]; int lev[N]; bool equal(double a,double b) { return abs(a-b)<1e-7; } struct Circle { int x,y,r; double gety(int f) { double dy=sqrt(1.0*r*r-1.0*(line-x)*(line-x)); return y+dy*f; } }cir[N]; struct Node { int id,tag; Node(){} Node(int id_,int tag_) : id(id_),tag(tag_) {} bool operator < (const Node p) const { double ya=cir[id].gety(tag),yb=cir[p.id].gety(p.tag); if(!equal(ya,yb)) return ya>yb; return tag>p.tag; } }; set<Node>s; bool cmp(Line p,Line q) { return p.xi<q.xi; } int main() { int n,k,ld,rd; set<Node>:: iterator l,r; scanf("%d",&n); int m=0; for(int i=0;i<n;++i) { scanf("%d%d%d",&cir[i].x,&cir[i].y,&cir[i].r); e[++m].id=i; e[m].xi=cir[i].x-cir[i].r; e[++m].id=i+n; e[m].xi=cir[i].x+cir[i].r; } sort(e+1,e+m+1,cmp); for(int i=1;i<=m;++i) { k=e[i].id%n; line=e[i].xi; if(e[i].id<n) { s.insert(Node(k,1)); l=s.lower_bound(Node(k,1)); r=l; r++; if(l==s.begin() || r==s.end()) lev[e[i].id]=1; else { l--; ld=(*l).id; rd=(*r).id; if(ld==rd) lev[e[i].id]=lev[ld]+1; else lev[e[i].id]=max(lev[ld],lev[rd]); } s.insert(Node(k,-1)); } else { s.erase(Node(k,1)); s.erase(Node(k,-1)); } } long long ans=0; for(int i=0;i<n;++i) if(lev[i]&1) ans+=1LL*cir[i].r*cir[i].r; else ans-=1LL*cir[i].r*cir[i].r; printf("%lld\n",ans); return 0; }
4561: [JLoi2016]圆的异或并
Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 923 Solved: 369
[Submit][Status][Discuss]
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
0 0 1
0 0 2
Sample Output
3