zoukankan      html  css  js  c++  java
  • 【BZOJ4561】[JLoi2016]圆的异或并

    传送门

    把圆拆成上下两个圆弧,因为不存在相交关系,圆弧直接的上下关系是不变的。

    用set维护这些圆弧,插入的时候upper_bound一下,如果找到的是上圆弧,就是我外面的第一个圆,否则我外面的第一个圆就是这个下圆弧外面的第一个圆。

    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<vector>
    #include<cstdio>
    #include<queue>
    #include<cmath>
    #include<set>
    #define For(i,a,b) for(int i=(a);i<=(b);i++)
    #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    const int N=400007;
    typedef long long LL;
    typedef double db;
    using namespace std;
    int n,cnt,f[N];
    db x[N],y[N],r[N],now;
    
    template<typename T>void read(T &x)  {
        char ch=getchar(); x=0; T f=1;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    struct node {
        int id,f;
        node(){}
        node(int id,int f):id(id),f(f){}
        friend bool operator <(const node&A,const node&B) {
            return x[A.id]+A.f*r[A.id]<x[B.id]+B.f*r[B.id];
        }
    }q[N];
    
    struct bow {
        int id,f;
        bow(){}
        bow(int id,int f):id(id),f(f){}
    };
    
    bool operator <(const bow&A,const bow&B) {
        db y1=(db)y[A.id]+(db)A.f*sqrt(r[A.id]*r[A.id]-(now-x[A.id])*(now-x[A.id]));
        db y2=(db)y[B.id]+(db)B.f*sqrt(r[B.id]*r[B.id]-(now-x[B.id])*(now-x[B.id]));
        return y1==y2?A.f<B.f:y1<y2;
    }
    
    set<bow>s;
    #define IT set<bow>::iterator
    
    //#define DEBUG
    int main() {
    #ifdef DEBUG
        freopen("4561.in","r",stdin);
        freopen("4561.out","w",stdout);
    #endif
        read(n);
        For(i,1,n) { read(x[i]); read(y[i]); read(r[i]); q[++cnt]=node(i,-1); q[++cnt]=node(i,1); }
        sort(q+1,q+cnt+1);
        For(i,1,cnt) {
            now=x[q[i].id]+q[i].f*r[q[i].id];
            if(q[i].f==-1) {
                IT it=s.upper_bound(bow(q[i].id,1));
                if(it!=s.end()) { 
                    bow tp=*it;
                    if(tp.f==-1) f[q[i].id]=f[tp.id];
                    else f[q[i].id]=-f[tp.id];
                }
                else f[q[i].id]=1;
                s.insert(bow(q[i].id,1)); s.insert(bow(q[i].id,-1));  
            }
            else s.erase(bow(q[i].id,1)),s.erase(bow(q[i].id,-1)) ;
        }
        db ans=0;
        For(i,1,n) 
            ans+=r[i]*r[i]*f[i];
        printf("%lld
    ",(LL)ans);
        return 0;
    }
    /*
    5
    -153 -765 50
    -51 -765 50
    0 867 50
    0 969 50
    0 969 47
    */
    View Code
  • 相关阅读:
    合并n个链表
    合并2个链表
    删除链表中的倒数第n个元素
    判断字符串是否回文字符串
    回文链表
    反转链表
    反转链表2
    冒泡排序法
    编译datax(3.x版本)踩的坑,记录修改记录
    Python基本知识(6)——集合
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8657846.html
Copyright © 2011-2022 走看看