Simpson积分(BZOJ2178)

lrj的代码常数太大T了QAQ,改了一下。

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
 
typedef double db;
const int N=1005;
int n,t,lm=10000,rm=-10000,v[N],q[N],x[N],y[N],r[N];
pair<db,db> b[N];
 
db F(db a) {
    int tt=0;
    db re=0,ls=-100000;
    for(int i=1;i<=t;i++) if(fabs(a-x[q[i]])<=r[q[i]]) {
        db k=sqrt(r[q[i]]*r[q[i]]-(a-x[q[i]])*(a-x[q[i]]));
        b[++tt].first=y[q[i]]-k,b[tt].second=y[q[i]]+k;
    }
    sort(b+1,b+1+tt);
    for(int i=1;i<=tt;i++) {
        if(b[i].first>ls) re+=b[i].second-b[i].first,ls=b[i].second;
        else if(b[i].second>ls) re+=b[i].second-ls,ls=b[i].second;
    }
    return re;
}
db asr(db a,db b,db c,db A,db B,db C) {
    db l=F((a+c)/2),r=F((c+b)/2),aa=(A+C*4+B)*(b-a)/6,L=(A+4*l+C)*(c-a)/6,R=(C+4*r+B)*(b-c)/6;
    if(fabs(L+R-aa)<=1e-13) return aa;
    return asr(a,c,(a+c)/2,A,C,l)+asr(c,b,(b+c)/2,C,B,r);
}
 
int main() {
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        scanf("%d%d%d",&x[i],&y[i],&r[i]);
        lm=min(lm,x[i]-r[i]),rm=max(rm,x[i]+r[i]);
    }
    for(int i=1;i<=n;i++) if(!v[i])
    for(int j=1;j<=n;j++) if(i!=j&&!v[j]) {
        if(sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]))+r[j]<=r[i]) v[j]=1;
    }
    for(int i=1;i<=n;i++) if(!v[i]) q[++t]=i;
    printf("%.3f",asr(lm,rm,(lm+rm)/2.0,0,0,F((lm+rm)/2.0)));
    return 0;
}
posted @ 2017-02-24 09:08  Monster_Yi  阅读(252)  评论(0编辑  收藏  举报