zoukankan      html  css  js  c++  java
  • 相关分析

    /*
        将原式化简,会发现最后只需要维护四个东西,分别是:Σx,Σy,Σx*y,Σx*x。
        区间加的时候x和y都很容易, 
        Σx*y=Σ(x+S)*(y+T)=Σx*y+S*Σy+T*Σx+len*S*T
        Σx*x=Σ(x+S)*(x+S)=Σx*x+2*S*Σx+len*S*S
        区间修改的时候
        Σ(i+S)*(i+T)=Σi*i+(S+T)*Σi+len*S*T
        Σ(i+S)*(i+S)=Σi*i+2*S*Σi+len*S*S
         
        注意区间加和区间修改的先后顺序,有区间修改时应该先修改在进行区间加;
        而有区间加的时候,可以直接进行区间修改。 
    */
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define N 400010 
    #define inf 1000000000
    using namespace std;
    const double eps=1e-8;
    int n,m,X[N],Y[N];
    double Xs[N],Ys[N],Sq[N],Mul[N],Xdlt[N],Ydlt[N];
    double Is[N],Is2[N],Xcov[N],Ycov[N];
    struct node{
        double sx,sy,sq,ml;
        node(){sx=sy=sq=ml=0;}
    };
    void update(int i){
        Xs[i]=Xs[i<<1]+Xs[(i<<1)+1];
        Ys[i]=Ys[i<<1]+Ys[(i<<1)+1];
        Sq[i]=Sq[i<<1]+Sq[(i<<1)+1];
        Mul[i]=Mul[i<<1]+Mul[(i<<1)+1];
    }
    void Cov(int i,int l,int r,double cx,double cy){
        double len=(r-l+1);
        Xdlt[i]=Ydlt[i]=0;
        Xcov[i]=cx;Ycov[i]=cy;
        Sq[i]=cx*cx*len+2*cx*Is[i]+Is2[i];
        Mul[i]=cx*cy*len+(cx+cy)*Is[i]+Is2[i];
        Xs[i]=cx*len+Is[i];Ys[i]=cy*len+Is[i];
    }
    void Add(int i,int l,int r,double dx,double dy){
        double len=r-l+1;
        if (Xcov[i]!=inf||Ycov[i]!=inf){
            Cov(i,l,r,Xcov[i]+dx,Ycov[i]+dy);
            return;
        }
        Xdlt[i]+=dx;Ydlt[i]+=dy;
        Sq[i]+=dx*dx*len+2*dx*Xs[i];
        Mul[i]+=dx*Ys[i]+dy*Xs[i]+dx*dy*len;
        Xs[i]+=dx*len;Ys[i]+=dy*len;
    }
    void pushdown(int i,int l,int r){
        if (Xdlt[i]!=0||Ydlt[i]!=0){
            int mid=(l+r)>>1;
            Add(i<<1,l,mid,Xdlt[i],Ydlt[i]);
            Add((i<<1)+1,mid+1,r,Xdlt[i],Ydlt[i]);
            Xdlt[i]=Ydlt[i]=0;
        }
        if (Xcov[i]!=inf||Ycov[i]!=inf){
            int mid=(l+r)>>1;
            Cov(i<<1,l,mid,Xcov[i],Ycov[i]);
            Cov((i<<1)+1,mid+1,r,Xcov[i],Ycov[i]);
            Xcov[i]=Ycov[i]=inf;
        }
    }
    void build(int i,int l,int r){
        Xcov[i]=Ycov[i]=inf;
        if (l==r){
            double xx=X[l],yy=Y[l];
            Xs[i]=xx;Ys[i]=yy;
            Sq[i]=xx*xx;Mul[i]=xx*yy;
            Is[i]=l;Is2[i]=(double)l*(double)l;
            return;
        }
        int mid=(l+r)>>1;
        build(i<<1,l,mid);
        build((i<<1)+1,mid+1,r);
        update(i);
        Is[i]=Is[i<<1]+Is[(i<<1)+1];
        Is2[i]=Is2[i<<1]+Is2[(i<<1)+1];
    }
    void ask(int i,int l,int r,int x,int y,node &ans){
        if (x<=l&&y>=r){
            ans.sx+=Xs[i];ans.sy+=Ys[i];
            ans.sq+=Sq[i];ans.ml+=Mul[i];
            return;
        }
        int mid=(l+r)>>1;
        pushdown(i,l,r);
        if (x<=mid) ask(i<<1,l,mid,x,y,ans);
        if (y>mid) ask((i<<1)+1,mid+1,r,x,y,ans);
    }
    double Getans(int l,int r){
        node tmp;
        double avex,avey,len=r-l+1,up,down;
        up=down=0;ask(1,1,n,l,r,tmp);
        avex=tmp.sx/len;avey=tmp.sy/len;
        down=tmp.sq-2*avex*tmp.sx+avex*avex*len;
        up=tmp.ml-avey*tmp.sx-avex*tmp.sy+avex*avey*len;
        return up/down+eps;
    }
    void add(int i,int l,int r,int x,int y,double s,double t){
        if (x<=l&&y>=r){Add(i,l,r,s,t);return;}
        int mid=(l+r)>>1;
        pushdown(i,l,r);
        if (x<=mid) add(i<<1,l,mid,x,y,s,t);
        if (y>mid) add((i<<1)+1,mid+1,r,x,y,s,t);
        update(i);
    }
    void cover(int i,int l,int r,int x,int y,double s,double t){
        if (x<=l&&y>=r){Cov(i,l,r,s,t);return;}
        int mid=(l+r)>>1;
        pushdown(i,l,r);
        if (x<=mid) cover(i<<1,l,mid,x,y,s,t);
        if (y>mid) cover((i<<1)+1,mid+1,r,x,y,s,t);
        update(i);
    }
    int main(){
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++) scanf("%d",&X[i]);
        for (int i=1;i<=n;i++) scanf("%d",&Y[i]);
        build(1,1,n);
        for (int i=1;i<=m;i++){
            int type,l,r,s,t;
            scanf("%d%d%d",&type,&l,&r);
            if (type==1) printf("%.10lf
    ",Getans(l,r));
            if (type==2){
                scanf("%d%d",&s,&t);
                add(1,1,n,l,r,s,t);
            }
            if (type==3){
                scanf("%d%d",&s,&t);
                cover(1,1,n,l,r,s,t);
            }
        }
        return 0;
    }
  • 相关阅读:
    正则表达式$的一些用法
    基本类型数据转换(int,char,byte)
    IntelliJ Idea 2017 免费激活方法
    jrebel license server 激活方法
    linux 完全关闭tomcat
    spring data jpa自定义bean字段映射
    idea 启动调试模式总提示端口58346被占用问题
    java使用jsch连接linux
    福大软工 · BETA 版冲刺前准备(团队)
    Alpha 事后诸葛亮
  • 原文地址:https://www.cnblogs.com/harden/p/6706149.html
Copyright © 2011-2022 走看看