zoukankan      html  css  js  c++  java
  • simpson

    使用二次函数拟合复杂的连续函数求积分

    对于(l,r)拟合的积分为(r-l)*(f(l)+4*f((l+r)/2)+f(r))/6

    ___________________________

    BZOJ2178

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #define LDB double
    using namespace std;
    
      const LDB eps=1e-13;
      LDB ans=0;
    
      struct data{
          LDB x,y,r,va;
      }a[1001],tmp[1001];
      
      int st,en,n,del[1001];
    
      int mycomp (const data&a,const data&b){
          return(a.va<b.va);
      }
      
      LDB dis(data a,data b){
          return(sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)));
      }
      
      LDB getf(LDB xx){
          int cnt=0;
          for (int i=st;i<=en;i++)
            if (fabs(a[i].x-xx)<a[i].r-eps){
              tmp[++cnt]=a[i];tmp[cnt].va=a[i].y-sqrt(a[i].r*a[i].r-(a[i].x-xx)*(a[i].x-xx));    
          }
        sort(tmp+1,tmp+cnt+1,mycomp);
        
        LDB ret=0;int po;
        for (int i=1;i<=cnt;i=po+1){
          po=i;LDB last=2*tmp[i].y-tmp[i].va;
          while (po<cnt&&tmp[po+1].va<last){
              po++;
              last=max(last,2*tmp[po].y-tmp[po].va);
          }
          ret+=(last-tmp[i].va);    
        }
        return(ret);  
      }
      
      LDB cal(LDB l,LDB r,LDB fl,LDB fmid,LDB fr){
          return((r-l)*(fl+4*fmid+fr)/6);
      }
      
      void simpson(LDB l,LDB r,LDB fl,LDB fmid,LDB fr){
          LDB mid=(l+r)/2;
          LDB mid1=(l+mid)/2,mid2=(mid+r)/2;
          LDB f1=getf(mid1),f2=getf(mid2);
          LDB num1=cal(l,r,fl,fmid,fr);
          LDB num2=cal(l,mid,fl,f1,fmid)+cal(mid,r,fmid,f2,fr);
          if (fabs(num1-num2)<eps) {ans+=num1;return;}
          simpson(l,mid,fl,f1,fmid);simpson(mid,r,fmid,f2,fr);
      }
      
      void work(){
          int po;LDB last;
          for (int i=1;i<=n;i=po+1){
            po=i,last=a[i].x+a[i].r;
          while (po<n&&a[po+1].x-a[po+1].r<last+eps){
              po++;
              last=max(last,a[po].x+a[po].r);
          }
          st=i;en=po;
          simpson(a[i].x-a[i].r,last,getf(a[i].x-a[i].r),getf((a[i].x-a[i].r+last)/2),getf(last));    
        }
      }
    
      int main(){      
        scanf("%d",&n);
        for (int i=1;i<=n;i++) scanf("%lf%lf%lf",&tmp[i].x,&tmp[i].y,&tmp[i].r);
        for (int i=1;i<=n;i++)
          for (int j=1;j<=n;j++)
            if (i!=j)
            if (dis(tmp[i],tmp[j])<tmp[j].r-tmp[i].r) {del[i]=1;break;}
        int cnt=0;
        for (int i=1;i<=n;i++)
          if (!del[i]) a[++cnt]=tmp[i],a[cnt].va=a[cnt].x-a[cnt].r;
        n=cnt;
        sort(a+1,a+n+1,mycomp);
        
        work();
        printf("%.3lf
    ",ans);
      }
  • 相关阅读:
    Zookeeper
    激活函数
    线程池
    用rand()和srand()产生伪随机数的方法总结 (转贴)
    连接SDE数据库代码
    ProgressBar
    ArcEngine+OpenGL之二系统平台搭建
    我所知道的ArcObjects开发(转)
    oracle wm_concat函数 乱码
    修改32位的AutoCAD2012,使其能在64位系统上安装
  • 原文地址:https://www.cnblogs.com/zhujiangning/p/6250176.html
Copyright © 2011-2022 走看看