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; }