codevs 5967 [SDOI2017]相关分析

[题解]

/*
WA://50分
last:(r-l+1)<-- (r-mid)
     (r-l+1)<-- (mid-l+1)
now:int mid=l+r>>1;
        tr[lc].sxy+=tr[lc].sx*addy[k]+tr[lc].sy*addx[k]+(real)(mid-l+1)*addx[k]*addy[k];
        tr[lc].sx2+=(real)(mid-l+1)*addx[k]*addx[k]+2.0*tr[lc].sx*addx[k];
        tr[lc].sx+=(real)(mid-l+1)*addx[k];
        tr[lc].sy+=(real)(mid-l+1)*addy[k];

        tr[rc].sxy+=tr[rc].sx*addy[k]+tr[rc].sy*addx[k]+(real)(r-mid)*addx[k]*addy[k];
        tr[rc].sx2+=(real)(r-mid)*addx[k]*addx[k]+2.0*tr[rc].sx*addx[k];
        tr[rc].sx+=(real)(r-mid)*addx[k];
        tr[rc].sy+=(real)(r-mid)*addy[k];
        addx[k]=addy[k]=0;
*/
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<iostream>
#define pf(x)((x)*(x))
#define lc k<<1
#define rc k<<1|1
#define setfile(x) freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);
using namespace std;
typedef double real;
const real inf=2e9;
const int N=2e5+5;
const int M=1e3+5;
int n,m,bsize;
real ax[N],ay[N];
struct sgt{real sx,sy,sxy,sx2;}tr[N<<2];
real addx[N<<2],addy[N<<2];
real setx[N<<2],sety[N<<2];
bool tag[N<<2];
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
sgt operator +(const sgt &a,const sgt &b){
    sgt c;
    c.sx=a.sx+b.sx;
    c.sy=a.sy+b.sy;
    c.sxy=a.sxy+b.sxy;
    c.sx2=a.sx2+b.sx2;
    return c;
}
inline real sumsq1(real l,real r){return (l+r)*(r-l+1)/2;}
inline real sumsq2(real l,real r){return (r*(r+1)*(r*2+1)-(l-1)*l*(l*2-1))/6;}
void updata(int k){
    tr[k].sx=tr[lc].sx+tr[rc].sx;
    tr[k].sy=tr[lc].sy+tr[rc].sy;
    tr[k].sxy=tr[lc].sxy+tr[rc].sxy;
    tr[k].sx2=tr[lc].sx2+tr[rc].sx2;
}
void build(int k,int l,int r){
//    tag[k]=0;
    if(l==r){
        tr[k].sx=ax[l];
        tr[k].sy=ay[l];
        tr[k].sxy=ax[l]*ay[l];
        tr[k].sx2=ax[l]*ax[l];
        return ;
    }
    int mid=l+r>>1;
    build(lc,l,mid);
    build(rc,mid+1,r);
    updata(k);
}
void pushdown(int k,int l,int r){
    if(l==r) return ;
    int mid=l+r>>1;
    if(addx[k]!=0||addy[k]!=0){
        if(tag[lc]){
            setx[lc]+=addx[k];
            sety[lc]+=addy[k];
        }
        else{
            addx[lc]+=addx[k];
            addy[lc]+=addy[k];
        }
        if(tag[rc]){
            setx[rc]+=addx[k];
            sety[rc]+=addy[k];
        }
        else{
            addx[rc]+=addx[k];
            addy[rc]+=addy[k];
        }
        int mid=l+r>>1;
        tr[lc].sxy+=tr[lc].sx*addy[k]+tr[lc].sy*addx[k]+(real)(mid-l+1)*addx[k]*addy[k];
        tr[lc].sx2+=(real)(mid-l+1)*addx[k]*addx[k]+2.0*tr[lc].sx*addx[k];
        tr[lc].sx+=(real)(mid-l+1)*addx[k];
        tr[lc].sy+=(real)(mid-l+1)*addy[k];

        tr[rc].sxy+=tr[rc].sx*addy[k]+tr[rc].sy*addx[k]+(real)(r-mid)*addx[k]*addy[k];
        tr[rc].sx2+=(real)(r-mid)*addx[k]*addx[k]+2.0*tr[rc].sx*addx[k];
        tr[rc].sx+=(real)(r-mid)*addx[k];
        tr[rc].sy+=(real)(r-mid)*addy[k];
        addx[k]=addy[k]=0;
    }
    if(tag[k]){
        tag[lc]=tag[rc]=1;
        setx[lc]=setx[k];
        setx[rc]=setx[k];
        sety[lc]=sety[k];
        sety[rc]=sety[k];

        real li1,li2,ri1,ri2;
        li1=sumsq1(l,mid);
        li2=sumsq2(l,mid);
        ri1=sumsq1(mid+1,r);
        ri2=sumsq2(mid+1,r);
        tr[lc].sxy=setx[k]*sety[k]*(real)(mid-l+1);
        tr[lc].sx2=setx[k]*setx[k]*(real)(mid-l+1);

        tr[lc].sx=setx[k]*(real)(mid-l+1)+li1;
        tr[lc].sy=sety[k]*(real)(mid-l+1)+li1;
        tr[lc].sxy+=li1*(setx[k]+sety[k])+li2;
        tr[lc].sx2+=2*li1*setx[k]+li2;

        tr[rc].sxy=setx[k]*sety[k]*(real)(r-mid);
        tr[rc].sx2=setx[k]*setx[k]*(real)(r-mid);
        tr[rc].sx=setx[k]*(real)(r-mid)+ri1;
        tr[rc].sy=sety[k]*(real)(r-mid)+ri1;
        tr[rc].sxy+=ri1*(setx[k]+sety[k])+ri2;
        tr[rc].sx2+=2*ri1*setx[k]+ri2;
        tag[k]=0;
    }

}
void change(int k,int l,int r,int x,int y,real s,real t){
    if(l==x&&r==y){
        tr[k].sxy+=tr[k].sx*t+tr[k].sy*s+(real)(r-l+1)*s*t;
        tr[k].sx2+=(real)(r-l+1)*s*s+2.0*tr[k].sx*s;
        tr[k].sx+=(real)(r-l+1)*s;
        tr[k].sy+=(real)(r-l+1)*t;
        if(tag[k]){
            setx[k]+=s;
            sety[k]+=t;
        }
        else{
            addx[k]+=s;
            addy[k]+=t;
        }
        return ;
    }
    pushdown(k,l,r);
    int mid=l+r>>1;
    if(y<=mid) change(lc,l,mid,x,y,s,t);
    else if(x>mid) change(rc,mid+1,r,x,y,s,t);
    else change(lc,l,mid,x,mid,s,t),change(rc,mid+1,r,mid+1,y,s,t);
    updata(k);
}
void cover(int k,int l,int r,int x,int y,real s,real t){

    if(l==x&&r==y){
        real li1,li2;
        li1=sumsq1(l,r);
        li2=sumsq2(l,r);
        tr[k].sxy=s*t*(real)(r-l+1);
        tr[k].sx2=s*s*(real)(r-l+1);
        tr[k].sx=s*(real)(r-l+1)+li1;
        tr[k].sy=t*(real)(r-l+1)+li1;
        tr[k].sxy+=li1*(s+t)+li2;
        tr[k].sx2+=2*li1*s+li2;

        tag[k]=1;
        setx[k]=s;
        sety[k]=t;
        addx[k]=addy[k]=0;
        return ;
    }
    pushdown(k,l,r);
    int mid=l+r>>1;
    if(y<=mid) cover(lc,l,mid,x,y,s,t);
    else if(x>mid) cover(rc,mid+1,r,x,y,s,t);
    else cover(lc,l,mid,x,mid,s,t),cover(rc,mid+1,r,mid+1,y,s,t);
    updata(k);
}
sgt query(int k,int l,int r,int x,int y){
    if(l==x&&r==y) return tr[k];
    pushdown(k,l,r);
    int mid=l+r>>1;
    if(y<=mid) return query(lc,l,mid,x,y);
    else if(x>mid) return query(rc,mid+1,r,x,y);
    else return query(lc,l,mid,x,mid)+query(rc,mid+1,r,mid+1,y);
}
real find(int x,int y){
    real X=0,Y=0,XY=0,X2=0,Xp,Yp,fz=0,fm=0,A;
    sgt ans=query(1,1,n,x,y);int l=x,r=y;
    X=ans.sx;
    Y=ans.sy;
    XY=ans.sxy;
    X2=ans.sx2;
    Xp=X/(real)(r-l+1);
    Yp=Y/(real)(r-l+1);
    fz=XY-X*Yp-Xp*Y+Xp*Yp*(r-l+1);
    fm=X2-2.0*X*Xp+Xp*Xp*(r-l+1);
//    if(fz==0||fm==0) return 0;
    return fz/fm;
}
void work(){
    build(1,1,n);
    real s,t;
    for(int i=1,opt,x,y;i<=m;i++){
        opt=read();x=read();y=read();
        if(opt==1) printf("%.7lf\n",find(x,y));
        if(opt==2) scanf("%lf%lf",&s,&t),change(1,1,n,x,y,s,t);
        if(opt==3) scanf("%lf%lf",&s,&t),cover(1,1,n,x,y,s,t);
    }
}
int main(){
    setfile(relative);
    n=read();m=read();
    for(int i=1;i<=n;i++) scanf("%lf",&ax[i]);
    for(int i=1;i<=n;i++) scanf("%lf",&ay[i]);
    work();
    fclose(stdin);
    fclose(stdout);
    return 0;
}
时间: 2024-10-26 07:52:18

codevs 5967 [SDOI2017]相关分析的相关文章

BZOJ4817 SDOI2017 相关分析

4821: [Sdoi2017]相关分析 Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special Judge Description Frank对天文学非常感兴趣,他经常用望远镜看星星,同时记录下它们的信息,比如亮度.颜色等等,进而估算出 星星的距离,半径等等.Frank不仅喜欢观测,还喜欢分析观测到的数据.他经常分析两个参数之间(比如亮度和 半径)是否存在某种关系.现在Frank要分析参数X与Y之间的关系.他有n组观测数据,第i组观测数据记录了

[Luogu 3707] SDOI2017 相关分析

[Luogu 3707] SDOI2017 相关分析 <题目链接> 前言 Capella 和 Frank 一样爱好天文学. 她常在冬季的夜晚,若有所思地望着东北方上空的五边形中,最为耀眼的一个顶点. 那一抹金黄曾带给她多少美好的遐想! 直到有一天,她做了这一题,并饱受线段树的折磨. 概述 这是一道区间操作的题目,解法有线段树与分块等. 题主选择线段树进行讲解(因为没用分块写这题). 准备与计算答案 首先要知道,线段树需要维护的数值有哪些. 先来看题目中所给的公式. \(\bar x = \fr

SDOI2017 相关分析

把两个式子拆开 Σ(xi-px)(yi-py) =Σ xiyi + py * Σ xi - px * Σ yi + Σ 1* px * py Σ (xi-px)² = Σ xi² +  px * Σ xi * 2  + Σ 1* px² 用线段树维护 Σxiyi , Σxi ,Σ yi , Σ xi² 同时维护两个标记:增加和修改 对于增加操作,假设给x增加a,给y增加b Σ (xi+a)(yi+b)= Σ xiyi + b * Σ xi + a * Σ yi + Σ 1*a*b Σ (xi +

codevs 5963 [SDOI2017]树点染色

 [题解]: #include<cstdio> #include<cstring> #include<iostream> using namespace std; const int N=1e5+5; struct edge{int v,next;}e[N<<1];int tot,head[N],cur[N]; int n,m,top,st[N<<1]; inline int read(){ int x=0,f=1;char ch=getchar

codevs 5965 [SDOI2017]新生舞会

分数规划的裸题. 不会分数规划的OIer.百度:胡伯涛<最小割模型在信息学竞赛中的应用> /* TLE1: last:add(i,j+n,1e9,(real)((real)a[i][j]-ans*(real)b[i][j])); now :add(i,j+n,1,(real)((real)a[i][j]-ans*(real)b[i][j])); TLE2: last:real l=eps,r=(real)u/(real)v,mid,ans=0,now; now :real l=0,r=(rea

codevs 5964 [SDOI2017]序列计数

 [题解] 官方题解就两句话. 写了三个版本的不同分值代码.看代码吧. 前导1 //f[i][j][1/0]表示长为i,sum mod p=j,是否已经选了质数的方案数 #include<cstdio> using namespace std; const int mod=20170408; const int N=1e6+1; int tot,prime[N/3];bool check[N]; int n,m,f[2][N][2];int p; void pre(){ n=1e6;check

codevs 5962 [SDOI2017]数字表格

输入描述 Input Description  [题解] 对于蓝色部分预处理前缀积. 然后在用除法分块搞一下. O(Q*sqrt(min(n,m))*logn+nlogn) #include<cstdio> #include<iostream> using namespace std; typedef long long ll; const int N=1e6+5; const ll mod=1e9+7; int T,n,m,tot,mu[N],prime[N/3];bool ch

[bzoj4821][Sdoi2017]相关分析

来自FallDream的博客,未经允许,请勿转载,谢谢. Frank对天文学非常感兴趣,他经常用望远镜看星星,同时记录下它们的信息,比如亮度.颜色等等,进而估算出星星的距离,半径等等.Frank不仅喜欢观测,还喜欢分析观测到的数据.他经常分析两个参数之间(比如亮度和半径)是否存在某种关系.现在Frank要分析参数X与Y之间的关系.他有n组观测数据,第i组观测数据记录了x_i和y_i.他需要一下几种操作1 L,R:用直线拟合第L组到底R组观测数据.用xx表示这些观测数据中x的平均数,用yy表示这些

洛谷P3707 [SDOI2017]相关分析

题目描述 Frank对天文学非常感兴趣,他经常用望远镜看星星,同时记录下它们的信息,比如亮度.颜色等等,进而估算出星星的距离,半径等等. Frank不仅喜欢观测,还喜欢分析观测到的数据.他经常分析两个参数之间(比如亮度和半径)是否存在某种关系. 现在Frank要分析参数XX 与YY 之间的关系.他有nn 组观测数据,第ii 组观测数据记录了x_ixi? 和y_iyi? .他需要一下几种操作 1 L,RL,R : 用直线拟合第LL 组到底RR 组观测数据.用\overline{x}x 表示这些观测