bzoj 4821: [Sdoi2017]相关分析 线段树

题意

Frank对天文学非常感兴趣,他经常用望远镜看星星,同时记录下它们的信息,比如亮度、颜色等等,进而估算出星星的距离,半径等等。Frank不仅喜欢观测,还喜欢分析观测到的数据。他经常分析两个参数之间(比如亮度和半径)是否存在某种关系。现在Frank要分析参数X与Y之间的关系。他有n组观测数据,第i组观测数据记录了x_i和y_i。他需要一下几种操作1 L,R:用直线拟合第L组到底R组观测数据。用xx表示这些观测数据中x的平均数,用yy表示这些观测数据中y的平均数,即
xx=Σx_i/(R-L+1)(L<=i<=R)
yy=Σy_i/(R-L+1)(L<=i<=R)
如果直线方程是y=ax+b,那么a应当这样计算:
a=(Σ(x_i-xx)(y_i-yy))/(Σ(x_i-xx)(x_i-xx)) (L<=i<=R)
你需要帮助Frank计算a。
2 L,R,S,T:
Frank发现测量数据第L组到底R组数据有误差,对每个i满足L <= i <= R,x_i需要加上S,y_i需要加上T。
3 L,R,S,T:
Frank发现第L组到第R组数据需要修改,对于每个i满足L <= i <= R,x_i需要修改为(S+i),y_i需要修改为(T+i)。
n,|S|,|T|<=10^5

分析

码农题。
把括号展开后维护相关信息即可。
注意会爆long long,要开double。

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

typedef double LL;

const int N=100005;

int n,m,x[N],y[N];
struct tree{LL sx,sy,s,x2;pair<LL,LL> tag1,tag2;}t[N*5];
pair<LL,LL> ori=make_pair(0,0);
LL s1,s2,s3,s4;

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

LL get_s1(int l,int r)
{
    return (LL)(l+r)*(r-l+1)/2;
}

LL get_s2(int l,int r)
{
    l--;
    return (LL)r*(r+1)*(r*2+1)/6-(LL)l*(l+1)*(l*2+1)/6;
}

void updata(int d)
{
    t[d].sx=t[d*2].sx+t[d*2+1].sx;
    t[d].sy=t[d*2].sy+t[d*2+1].sy;
    t[d].s=t[d*2].s+t[d*2+1].s;
    t[d].x2=t[d*2].x2+t[d*2+1].x2;
}

void pushdown(int d,int L,int R)
{
    if (L==R)
    {
        t[d].tag1=t[d].tag2=ori;
        return;
    }
    int mid=(L+R)/2;
    if (t[d].tag1!=ori)
    {
        LL S=t[d].tag1.first,T=t[d].tag1.second;t[d].tag1=ori;
        t[d*2].tag2=t[d*2+1].tag2=ori;
        t[d*2].tag1=t[d*2+1].tag1=make_pair(S,T);
        int l=L,r=mid;
        t[d*2].x2=get_s2(l,r)+(LL)S*S*(r-l+1)+(LL)2*S*get_s1(l,r);t[d*2].sx=get_s1(l,r)+(LL)S*(r-l+1);t[d*2].sy=get_s1(l,r)+(LL)T*(r-l+1);t[d*2].s=(LL)S*T*(r-l+1)+(LL)(S+T)*get_s1(l,r)+(LL)get_s2(l,r);
        l=mid+1;r=R;
        t[d*2+1].x2=get_s2(l,r)+(LL)S*S*(r-l+1)+(LL)2*S*get_s1(l,r);t[d*2+1].sx=get_s1(l,r)+(LL)S*(r-l+1);t[d*2+1].sy=get_s1(l,r)+(LL)T*(r-l+1);t[d*2+1].s=(LL)S*T*(r-l+1)+(LL)(S+T)*get_s1(l,r)+(LL)get_s2(l,r);
    }
    if (t[d].tag2!=ori);
    {
        LL S=t[d].tag2.first,T=t[d].tag2.second;t[d].tag2=make_pair(0,0);
        t[d*2].tag2.first+=S;t[d*2].tag2.second+=T;
        t[d*2+1].tag2.first+=S;t[d*2+1].tag2.second+=T;
        int l=L,r=mid;
        t[d*2].x2+=(LL)S*S*(r-l+1)+(LL)2*t[d*2].sx*S,t[d*2].s+=(LL)S*T*(r-l+1)+(LL)t[d*2].sx*T+(LL)t[d*2].sy*S;t[d*2].sx+=(LL)S*(r-l+1);t[d*2].sy+=(LL)T*(r-l+1);
        l=mid+1;r=R;
        t[d*2+1].x2+=(LL)S*S*(r-l+1)+(LL)2*t[d*2+1].sx*S,t[d*2+1].s+=(LL)S*T*(r-l+1)+(LL)t[d*2+1].sx*T+(LL)t[d*2+1].sy*S;t[d*2+1].sx+=(LL)S*(r-l+1);t[d*2+1].sy+=(LL)T*(r-l+1);
    }
}

void build(int d,int l,int r)
{
    if (l==r)
    {
        t[d].sx=x[l];t[d].sy=y[l];t[d].s=(LL)x[l]*y[l];t[d].x2=(LL)x[l]*x[l];
        return;
    }
    int mid=(l+r)/2;
    build(d*2,l,mid);build(d*2+1,mid+1,r);
    updata(d);
}


void query(int d,int l,int r,int x,int y)
{
    if (x>y) return;
    pushdown(d,l,r);
    if (l==x&&r==y)
    {
        s1+=t[d].sx;s2+=t[d].sy;s3+=t[d].s;s4+=t[d].x2;
        return;
    }
    int mid=(l+r)/2;
    query(d*2,l,mid,x,min(y,mid));
    query(d*2+1,mid+1,r,max(x,mid+1),y);
}

void ins(int d,int l,int r,int x,int y,int S,int T,int op)
{
    if (x>y) return;
    pushdown(d,l,r);
    if (l==x&&r==y)
    {
        if (op==2) t[d].x2+=(LL)S*S*(r-l+1)+(LL)2*t[d].sx*S,t[d].s+=(LL)S*T*(r-l+1)+(LL)t[d].sx*T+(LL)t[d].sy*S,t[d].sx+=(LL)S*(r-l+1),t[d].sy+=(LL)T*(r-l+1),t[d].tag2=make_pair(S,T);
        else t[d].x2=get_s2(l,r)+(LL)S*S*(r-l+1)+(LL)2*S*get_s1(l,r),t[d].sx=get_s1(l,r)+(LL)S*(r-l+1),t[d].sy=get_s1(l,r)+(LL)T*(r-l+1),t[d].s=(LL)S*T*(r-l+1)+(LL)(S+T)*get_s1(l,r)+(LL)get_s2(l,r),t[d].tag1=make_pair(S,T);
        return;
    }
    int mid=(l+r)/2;
    ins(d*2,l,mid,x,min(y,mid),S,T,op);
    ins(d*2+1,mid+1,r,max(x,mid+1),y,S,T,op);
    updata(d);
}

int main()
{
    n=read();m=read();
    for (int i=1;i<=n;i++) x[i]=read();
    for (int i=1;i<=n;i++) y[i]=read();
    build(1,1,n);
    while (m--)
    {
        int op=read(),l=read(),r=read();
        if (op==1)
        {
            s1=0;s2=0;s3=0;s4=0;
            query(1,1,n,l,r);
            double xx=(double)s1/(r-l+1),yy=(double)s2/(r-l+1);
            double ans1=s3-yy*s1-xx*s2+(r-l+1)*xx*yy;
            double ans2=s4-(double)2*xx*s1+(double)(r-l+1)*xx*xx;
            printf("%.10lf\n",ans1/ans2);
        }
        else
        {
            int s=read(),t=read();
            ins(1,1,n,l,r,s,t,op);
        }
    }
    return 0;
}
Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值