bzoj 2178 圆的面积并simpson积分

Posted lokiii

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 2178 圆的面积并simpson积分相关的知识,希望对你有一定的参考价值。

直接套simpson,f可以直接把圆排序后扫一遍所有圆,这样维护一个区间就可以避免空段。
然而一定要去掉被其他圆完全覆盖的圆,否则会TLE

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const double eps=1e-13;
const int N=1005;
int n,m;
double mn=1e13,mx=-1e13;
bool fl[N];
struct cir
{
    double x,y,r;
    double operator < (const cir &a) const
    {
        return r<a.r;
    }
}c[N];
struct qwe
{
    double l,r;
    qwe(double L=0,double R=0)
    {
        l=L,r=R;
    }
    bool operator < (const qwe &a) const
    {
        return l<a.l;
    }
}a[N];
int cmp(double x)
{
    if(x<=eps&&x>=-eps)
        return 0;
    return x>0?1:-1;
}
double f(double x)
{
    int cnt=0;
    for(int i=1;i<=n;i++)
    {
        double dis=fabs(c[i].x-x);
        if(cmp(dis-c[i].r)<0)
        {
            double len=sqrt(c[i].r*c[i].r-dis*dis);
            a[++cnt]=qwe(c[i].y-len,c[i].y+len);
        }
    }
    if(!cnt)
        return 0;
    sort(a+1,a+1+cnt);
    double l=a[1].l,r=a[1].r,ans=0;
    for(int i=2;i<=cnt;i++)
    {
        if(cmp(a[i].l-r)<=0)
            r=max(r,a[i].r);
        else
            ans+=r-l,l=a[i].l,r=a[i].r;
    }
    ans+=r-l;
    return ans;
}
double sps(double l,double r,double now,double fl,double fr,double fm)
{
    double mid=(l+r)/2,ffl=f((l+mid)/2),ffr=f((mid+r)/2),p=(fl+fm+ffl*4)*(mid-l)/6,q=(fm+fr+ffr*4)*(r-mid)/6;
    if(cmp(now-p-q)==0)
        return now;
    else
        return sps(l,mid,p,fl,fm,ffl)+sps(mid,r,q,fm,fr,ffr);
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lf%lf%lf",&c[i].x,&c[i].y,&c[i].r);
        mn=min(mn,c[i].x-c[i].r),mx=max(mx,c[i].x+c[i].r);
    }//cout<<"OK"<<endl;
    sort(c+1,c+1+n);
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
            if(cmp(sqrt((c[i].x-c[j].x)*(c[i].x-c[j].x)+(c[i].y-c[j].y)*(c[i].y-c[j].y))+c[i].r-c[j].r)<=0)
            {       
                fl[i]=1;
                break;
            }
    for(int i=1;i<=n;i++)
        if(!fl[i])
            c[++m]=c[i];
    n=m;
    double fl=f(mn),fr=f(mx),fm=f((mn+mx)/2);
    printf("%.3lf\n",sps(mn,mx,(fl+4*fm+fr)*(mx-mn)/6,fl,fr,fm));
    return 0;
}

以上是关于bzoj 2178 圆的面积并simpson积分的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 2178: 圆的面积并 [辛普森积分 区间并]

BZOJ 2178 Simpson积分

bzoj 2178 自适应Simpson积分

BZOJ1502[NOI2005]月下柠檬树 Simpson积分

bzoj 1502 月下柠檬树Simpson积分

[BZOJ 1502][NOI2005]月下柠檬树(自适应Simpson积分)