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 MB
Submit: 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

Sample Output

3
posted @ 2020-01-18 21:28  TRTTG  阅读(138)  评论(0编辑  收藏  举报