Bzoj4561 [JLoi2016]圓的異或並
阿新 • • 發佈:2017-05-26
res ras nbsp ans 圓心 一個 esp 括號序列 pri Time Limit: 30 Sec Memory Limit: 256 MB
Submit: 521 Solved: 224
0 0 1
0 0 2
Submit: 521 Solved: 224
Description
在平面直角坐標系中給定N個圓。已知這些圓兩兩沒有交點,即兩圓的關系只存在相離和包含。求這些圓的異或面
積並。異或面積並為:當一片區域在奇數個圓內則計算其面積,當一片區域在偶數個圓內則不考慮。Input
第一行包含一個正整數N,代表圓的個數。接下來N行,每行3個非負整數x,y,r,表示一個圓心在(x,y),半徑為r的
圓。保證|x|,|y|,≤10^8,r>0,N<=200000Output
僅一行一個整數,表示所有圓的異或面積並除以圓周率Pi的結果。
Sample Input
20 0 1
0 0 2
Sample Output
3HINT
Source
幾何 思路題
圓之間沒有交點是一個很好的性質,這保證如果圓A被圓B包含,我們從某個方向掃描的時候一定先掃到圓B。
用set維護一個“括號序列”,對於當前的掃描線x,圓與x靠下的交點記為左括號,靠上的交點記為右括號,查詢當前圓在幾層括號裏,若在奇數層就減去這個圓的面積,否則加上
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4#include<cmath> 5 #include<cstring> 6 #include<set> 7 #define LL long long 8 using namespace std; 9 const int mxn=200010; 10 int read(){ 11 int x=0,f=1;char ch=getchar(); 12 while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} 13 while(ch>=‘0‘ && ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 14 return x*f; 15 } 16 struct cir{ 17 int x,y,r; 18 }c[mxn]; 19 struct node{ 20 int id; 21 int x,mk; 22 }p[mxn<<1]; 23 int tmp,cnt=0; 24 bool operator < (const node &a,const node &b) { 25 double res1=c[a.id].y+a.mk*sqrt((LL)c[a.id].r*c[a.id].r-((LL)tmp-c[a.id].x)*(tmp-c[a.id].x)); 26 double res2=c[b.id].y+b.mk*sqrt((LL)c[b.id].r*c[b.id].r-((LL)tmp-c[b.id].x)*(tmp-c[b.id].x)); 27 return (res1==res2 && a.mk<b.mk) || (res1<res2); 28 } 29 bool cmp (const node a,const node b){ 30 return a.x<b.x; 31 } 32 set<node>st; 33 int n,f[mxn]; 34 LL ans=0; 35 int main(){ 36 int i,j; 37 n=read(); 38 for(i=1;i<=n;i++){ 39 c[i].x=read();c[i].y=read();c[i].r=read(); 40 p[++cnt]=(node){i,c[i].x-c[i].r,1}; 41 p[++cnt]=(node){i,c[i].x+c[i].r,-1}; 42 } 43 sort(p+1,p+cnt+1,cmp); 44 for(i=1;i<=cnt;i++){ 45 tmp=p[i].x; 46 if(p[i].mk==1){ 47 set<node>::iterator it; 48 it=st.upper_bound((node){p[i].id,0,-1}); 49 if(it==st.end())f[p[i].id]=1; 50 else{ 51 if( (*it).mk==1 ) f[p[i].id]=-f[(*it).id]; 52 else f[p[i].id]=f[(*it).id]; 53 } 54 st.insert((node){p[i].id,0,1}); 55 st.insert((node){p[i].id,0,-1}); 56 } 57 else{ 58 st.erase((node){p[i].id,0,1}); 59 st.erase((node){p[i].id,0,-1}); 60 } 61 } 62 for(i=1;i<=n;i++){ 63 ans+=f[i]*(LL)c[i].r*c[i].r; 64 } 65 printf("%lld\n",ans); 66 return 0; 67 }
Bzoj4561 [JLoi2016]圓的異或並