相关分析

Time Limit: 10 Sec  Memory Limit: 128 MB
[Submit][Status][Discuss]

Description

  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)。

Input

  第一行两个数n,m,表示观测数据组数和操作次数。
  接下来一行n个数,第i个数是x_i。
  接下来一行n个数,第i个数是y_i。
  接下来m行,表示操作,格式见题目描述。
  保证1操作不会出现分母为0的情况。

Output

  对于每个1操作,输出一行,表示直线斜率a。
  选手输出与标准输出的绝对误差不超过10^-5即为正确。

Sample Input

  3 5
  1 2 3
  1 2 3
  1 1 3
  2 2 3 -3 2
  1 1 2
  3 1 2 2 1
  1 1 3

Sample Output

  1.0000000000
  -1.5000000000
  -0.6153846154

HINT

  1<=n,m<=10^5,0<=|S|,|T|,|x_i|,|y_i|<=10^5

Main idea

  维护一个线性回归方程,需要支持区间加,区间覆盖等差数列。

Solution

  我们先化一个式子:

  然后就只要运用线段树维护 Σx Σy Σxx Σxy 就可以了。

  每一个具体怎么维护的话,就是把式子列出来,暴力展开一下看一下其中的关联即可,并不难(BearChild懒得写啦!)。

Code

 #include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long s64; const int ONE = ; int n,m,P;
int L,R,S,T;
double Sumsq[ONE];
double Vx[ONE],Vy[ONE]; struct power
{
double sumx,sumy,sumxx,sumxy;
double addx,addy;
double covx,covy;
bool cov;
}Node[ONE*]; struct ans
{
double x,y,xx,xy;
}res; inline int get()
{
int res=,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} void Covers(int i,int l,int r,double S,double T)
{
if(l > r) return;
double len = r-l+; double sum = (l+r)*len/;
Node[i].addx = Node[i].addy = ;
Node[i].covx = S; Node[i].covy = T;
Node[i].cov = ;
Node[i].sumxx = S*S*len + sum*S + sum*S + Sumsq[r] - Sumsq[l-];
Node[i].sumxy = S*T*len + sum*S + sum*T + Sumsq[r] - Sumsq[l-];
Node[i].sumx = (S+l + S+r)*len / ;
Node[i].sumy = (T+l + T+r)*len / ;
} void PC(int i,int l,int r)
{
if(Node[i].cov)
{
int mid = l+r>>;
Covers(i<<,l,mid, Node[i].covx,Node[i].covy);
Covers(i<<|,mid+,r, Node[i].covx,Node[i].covy);
Node[i].cov = ;
}
} void Update(int i,int l,int r,double S,double T)
{
if(l > r) return;
PC(i,l,r);
double len = r-l+;
Node[i].addx += S; Node[i].addy += T;
Node[i].sumxx += *S*Node[i].sumx + S*S*len;
Node[i].sumxy += S*Node[i].sumy + T*Node[i].sumx + S*T*len;
Node[i].sumx += S*len; Node[i].sumy += T*len;
} void PU(int i,int l,int r)
{
if(Node[i].addx || Node[i].addy)
{
int mid = l+r>>;
Update(i<<,l,mid, Node[i].addx,Node[i].addy);
Update(i<<|,mid+,r, Node[i].addx,Node[i].addy);
Node[i].addx = Node[i].addy = ;
}
} void pushdown(int i,int l,int r)
{
PU(i,l,r); PC(i,l,r);
} void Renew(int i)
{
int a = i<<, b = i<<|;
Node[i].sumx = Node[a].sumx + Node[b].sumx;
Node[i].sumy = Node[a].sumy + Node[b].sumy;
Node[i].sumxx = Node[a].sumxx + Node[b].sumxx;
Node[i].sumxy = Node[a].sumxy + Node[b].sumxy;
} void Build(int i,int l,int r)
{
if(l==r)
{
Node[i].sumx = Vx[l];
Node[i].sumy = Vy[l];
Node[i].sumxx = (double)Vx[l] * Vx[l];
Node[i].sumxy = (double)Vx[l] * Vy[l];
return;
}
int mid = l+r>>;
Build(i<<,l,mid); Build(i<<|,mid+,r);
Renew(i);
} void Cov(int i,int l,int r,int L,int R,double S,double T)
{
if(L<=l && r<=R)
{
Covers(i,l,r,S,T);
return;
} pushdown(i,l,r);
int mid = l+r>>;
if(L<=mid) Cov(i<<,l,mid,L,R,S,T);
if(mid+<=R) Cov(i<<|,mid+,r,L,R,S,T);
Renew(i);
} void Add(int i,int l,int r,int L,int R,double S,double T)
{
if(L<=l && r<=R)
{
Update(i,l,r,S,T);
return;
} pushdown(i,l,r);
int mid = l+r>>;
if(L<=mid) Add(i<<,l,mid,L,R,S,T);
if(mid+<=R) Add(i<<|,mid+,r,L,R,S,T);
Renew(i);
} void Query(int i,int l,int r,int L,int R)
{
if(L<=l && r<=R)
{
res.x += Node[i].sumx; res.y += Node[i].sumy;
res.xx += Node[i].sumxx; res.xy += Node[i].sumxy;
return;
} pushdown(i,l,r);
int mid = l+r>>;
if(L<=mid) Query(i<<,l,mid,L,R);
if(mid+<=R) Query(i<<|,mid+,r,L,R);
} int main()
{
for(int i=;i<=ONE-;i++) Sumsq[i] = Sumsq[i-] + (double)i*i; n=get(); m=get();
for(int i=;i<=n;i++) Vx[i]=get();
for(int i=;i<=n;i++) Vy[i]=get();
Build(,,n); while(m--)
{
P = get(); L = get(); R = get();
if(P == )
{
res.x = res.y = res.xx = res.xy = ;
Query(,,n,L,R);
double len = R-L+;
double Avex = res.x / len;
double Avey = res.y / len;
printf("%.6lf\n", (res.xy - len * Avex * Avey) / (res.xx - len*Avex*Avex));
}
else
{
S = get(); T = get();
if(P == ) Add(,,n, L,R,S,T);
else Cov(,,n, L,R,S,T);
}
}
}

【BZOJ4821】【SDOI2017】相关分析 [线段树]的更多相关文章

  1. 【BZOJ4821】[Sdoi2017]相关分析 线段树

    [BZOJ4821][Sdoi2017]相关分析 Description Frank对天文学非常感兴趣,他经常用望远镜看星星,同时记录下它们的信息,比如亮度.颜色等等,进而估算出星星的距离,半径等等. ...

  2. [Sdoi2017]相关分析 [线段树]

    [Sdoi2017]相关分析 题意:沙茶线段树 md其实我考场上还剩一个多小时写了40分 其实当时写正解也可以吧1h也就写完了不过还要拍一下 正解代码比40分短2333 #include <io ...

  3. BZOJ 4821 [Sdoi2017]相关分析 ——线段树

    打开题面,看到许多$\sum$ woc,好神啊,SDOI好强啊 然后展开之后,woc,SDOI好弱啊,怎么T3出个线段树裸题啊. 最后写代码的时候,woc,SDOI怎么出个这么码农的题啊,怎么调啊. ...

  4. 洛谷P3707 [SDOI2017]相关分析(线段树)

    题目描述 Frank对天文学非常感兴趣,他经常用望远镜看星星,同时记录下它们的信息,比如亮度.颜色等等,进而估算出星星的距离,半径等等. Frank不仅喜欢观测,还喜欢分析观测到的数据.他经常分析两个 ...

  5. BZOJ 4821: [Sdoi2017]相关分析 线段树 + 卡精

    考试的时候切掉了,然而卡精 + 有一个地方忘开 $long long$,完美挂掉 $50$pts. 把式子化简一下,然后直接拿线段树来维护即可. Code: // luogu-judger-enabl ...

  6. BZOJ.4821.[SDOI2017]相关分析(线段树)

    BZOJ LOJ 洛谷 恶心的拆式子..然后就是要维护\(\sum x_i,\ \sum y_i,\ \sum x_iy_i,\ \sum x_i^2\). 操作三可以看成初始化一遍,然后同操作二. ...

  7. SDOI2017相关分析 线段树

    题目 https://loj.ac/problem/2005 思路 \[ \sum_{L}^{R}{(x_i-x)^{2}} \] \[ \sum_{L}^{R}{(x_i^2-2*x_i*x+x^{ ...

  8. luogu3707 相关分析 (线段树)

    把式子展开以后会发现,可以用线段树维护$x,y,x*y,x^2$分别的区间和 然后操作有区间加和区间修改 这个pushdown的时候,如果改和加的标记同时存在,那一定是先改再加,要不然加的标记已经被清 ...

  9. BZOJ4821 SDOI2017相关分析(线段树)

    纯粹的码农题.维护x的和.y的和.xy的和.x2的和即可.可能会炸long long. #include<iostream> #include<cstdio> #include ...

随机推荐

  1. JavaBean中DAO设计模式简介

    一.信息系统的开发架构 客户层-------显示层-------业务层---------数据层---------数据库 1.客户层:客户层就是客户端,简单的来说就是浏览器. 2.显示层:JSP/Ser ...

  2. Python实现XML的操作

    本文从以下两个方面, 用Python实现XML的操作: 一. minidom写入XML示例1 二. minidom写入XML示例2 三. ElementTree写入/修改示例 四. ElementTr ...

  3. mysql通过binlog恢复数据

    如果mysql不小心操作失误导致数据错误或者丢失这时候binlog起到了很大的作用 恢复有几种方式 1.按时间恢复--start-datetime   如果确定了时间点,那么按时间恢复是一个再好不过的 ...

  4. 第29天:js-数组添加删除、数组和字符串相互转换

    一.添加数组var arr=[1,3,5];arr.push(7,9);//添加7和9到数组arr后面,得到[1,3,5,7,9]1.push();可向数组末尾添加一个或多个元素,并返回新的长度.2. ...

  5. BZOJ 1076 奖励关(状压期望DP)

    当前得分期望=(上一轮得分期望+这一轮得分)/m dp[i,j]:第i轮拿的物品方案为j的最优得分期望 如果我们正着去做,会出现从不合法状态(比如前i个根本无法达到j这种方案),所以从后向前推 如果当 ...

  6. shell脚本学习—条件测试和循环语句

    条件测试 1. 条件测试:test [ 命令test或[可以测试一个条件是否成立,如果测试结果为真,则该命令的Exit Status为0,如果测试结果为假, 则命令的Exit Status为1(注意与 ...

  7. WPF 进度条ProgressBar

    今天研究了一下wpf的进度条ProgressBar 1.传统ProgressBar WPF进度条ProgressBar 这个控件,如果直接写到循环里,会死掉,界面会卡死,不会有进度.需要把进度条放到单 ...

  8. 个人vim配置

    YouCompletMe支持golang cd .vim/bundle/YouCompleteMe ./install.sh --clang-completer --go-completer clan ...

  9. BZOJ4651 & 洛谷1173 & UOJ220:[NOI2016]网格——题解(附debug数据)

    https://www.lydsy.com/JudgeOnline/problem.php?id=4651 https://www.luogu.org/problemnew/show/P1173#su ...

  10. CF359D:Pair of Numbers——题解

    https://vjudge.net/problem/CodeForces-359D http://codeforces.com/problemset/problem/359/D 题目大意: 给一串数 ...