相关分析

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. lintcode-151-买卖股票的最佳时机 III

    151-买卖股票的最佳时机 III 假设你有一个数组,它的第i个元素是一支给定的股票在第i天的价格.设计一个算法来找到最大的利润.你最多可以完成两笔交易. 注意事项 你不可以同时参与多笔交易(你必须在 ...

  2. 个人作业4 alpha阶段 个人总结

    一.个人总结 二.回答问题 三.再提问题 Q1:关于第三章过早优化 过早优化:既然软件是"软"的,那么它就有很大的可塑性,可以不断改进.放眼望去,一个复杂的软件似乎很多的模块都可以 ...

  3. node中的__dirname

    先说结论:__dirname指的是当前文件所在文件夹的绝对路径. 测试路径如下: 即 根目录/dir0.js 根目录/path1/dir1.js 根目录/paht1/path2/dir2.js 每个d ...

  4. C#多线程间的同步问题

    使用线程时最头痛的就是共享资源的同步问题,处理不好会得到错误的结果,C#处理共享资源有以下几种: 1.lock锁 需要注意的地方: 1).lock不能锁定空值某一对象可以指向Null,但Null是不需 ...

  5. Android Shimmer 发光微光动画

    这是Facebook提供的一个类库(题外话http://code.facebook.com,这里有很多好玩有趣有用的Facebook开源的类库) 这么炫酷的发光动画效果,想必很多Android码农都会 ...

  6. shell脚本学习—Shell执行脚本

    Shell作用是解释执行用户的命令,用户输入一条命令,Shell就解释执行这一条,这种方式称为交互式,但还有另一种执行命令的方式称为批处理方式,用户事先写一个Shell脚本,Shell可以一次把这些命 ...

  7. Linq里where出现null的问题

    今天遇到一个问题,怎么在where里判断一个字段是否为null,并且这个字段不是字符串string类型,而是int和GUID类型,折腾了半天终于搞明白了.(由于项目是我半路接手的,问题是前期的同事给我 ...

  8. 【刷题】BZOJ 1143 [CTSC2008]祭祀river

    Description 在遥远的东方,有一个神秘的民族,自称Y族.他们世代居住在水面上,奉龙王为神.每逢重大庆典, Y族都会在水面上举办盛大的祭祀活动.我们可以把Y族居住地水系看成一个由岔口和河道组成 ...

  9. 用Matlab对数据进行线性拟合算法

    http://www.cnblogs.com/softlin/p/5965939.html 挖坑

  10. [ZJOI2011]最小割 & [CQOI2016]不同的最小割 分治求最小割

    题面: [ZJOI2011]最小割 [CQOI2016]不同的最小割 题解: 其实这两道是同一道题.... 最小割是用的dinic,不同的最小割是用的isap 其实都是分治求最小割 简单讲讲思路吧 就 ...