相关分析

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

  1. #include<iostream>
  2. #include<string>
  3. #include<algorithm>
  4. #include<cstdio>
  5. #include<cstring>
  6. #include<cstdlib>
  7. #include<cmath>
  8. using namespace std;
  9. typedef long long s64;
  10.  
  11. const int ONE = ;
  12.  
  13. int n,m,P;
  14. int L,R,S,T;
  15. double Sumsq[ONE];
  16. double Vx[ONE],Vy[ONE];
  17.  
  18. struct power
  19. {
  20. double sumx,sumy,sumxx,sumxy;
  21. double addx,addy;
  22. double covx,covy;
  23. bool cov;
  24. }Node[ONE*];
  25.  
  26. struct ans
  27. {
  28. double x,y,xx,xy;
  29. }res;
  30.  
  31. inline int get()
  32. {
  33. int res=,Q=; char c;
  34. while( (c=getchar())< || c>)
  35. if(c=='-')Q=-;
  36. if(Q) res=c-;
  37. while((c=getchar())>= && c<=)
  38. res=res*+c-;
  39. return res*Q;
  40. }
  41.  
  42. void Covers(int i,int l,int r,double S,double T)
  43. {
  44. if(l > r) return;
  45. double len = r-l+; double sum = (l+r)*len/;
  46. Node[i].addx = Node[i].addy = ;
  47. Node[i].covx = S; Node[i].covy = T;
  48. Node[i].cov = ;
  49. Node[i].sumxx = S*S*len + sum*S + sum*S + Sumsq[r] - Sumsq[l-];
  50. Node[i].sumxy = S*T*len + sum*S + sum*T + Sumsq[r] - Sumsq[l-];
  51. Node[i].sumx = (S+l + S+r)*len / ;
  52. Node[i].sumy = (T+l + T+r)*len / ;
  53. }
  54.  
  55. void PC(int i,int l,int r)
  56. {
  57. if(Node[i].cov)
  58. {
  59. int mid = l+r>>;
  60. Covers(i<<,l,mid, Node[i].covx,Node[i].covy);
  61. Covers(i<<|,mid+,r, Node[i].covx,Node[i].covy);
  62. Node[i].cov = ;
  63. }
  64. }
  65.  
  66. void Update(int i,int l,int r,double S,double T)
  67. {
  68. if(l > r) return;
  69. PC(i,l,r);
  70. double len = r-l+;
  71. Node[i].addx += S; Node[i].addy += T;
  72. Node[i].sumxx += *S*Node[i].sumx + S*S*len;
  73. Node[i].sumxy += S*Node[i].sumy + T*Node[i].sumx + S*T*len;
  74. Node[i].sumx += S*len; Node[i].sumy += T*len;
  75. }
  76.  
  77. void PU(int i,int l,int r)
  78. {
  79. if(Node[i].addx || Node[i].addy)
  80. {
  81. int mid = l+r>>;
  82. Update(i<<,l,mid, Node[i].addx,Node[i].addy);
  83. Update(i<<|,mid+,r, Node[i].addx,Node[i].addy);
  84. Node[i].addx = Node[i].addy = ;
  85. }
  86. }
  87.  
  88. void pushdown(int i,int l,int r)
  89. {
  90. PU(i,l,r); PC(i,l,r);
  91. }
  92.  
  93. void Renew(int i)
  94. {
  95. int a = i<<, b = i<<|;
  96. Node[i].sumx = Node[a].sumx + Node[b].sumx;
  97. Node[i].sumy = Node[a].sumy + Node[b].sumy;
  98. Node[i].sumxx = Node[a].sumxx + Node[b].sumxx;
  99. Node[i].sumxy = Node[a].sumxy + Node[b].sumxy;
  100. }
  101.  
  102. void Build(int i,int l,int r)
  103. {
  104. if(l==r)
  105. {
  106. Node[i].sumx = Vx[l];
  107. Node[i].sumy = Vy[l];
  108. Node[i].sumxx = (double)Vx[l] * Vx[l];
  109. Node[i].sumxy = (double)Vx[l] * Vy[l];
  110. return;
  111. }
  112. int mid = l+r>>;
  113. Build(i<<,l,mid); Build(i<<|,mid+,r);
  114. Renew(i);
  115. }
  116.  
  117. void Cov(int i,int l,int r,int L,int R,double S,double T)
  118. {
  119. if(L<=l && r<=R)
  120. {
  121. Covers(i,l,r,S,T);
  122. return;
  123. }
  124.  
  125. pushdown(i,l,r);
  126. int mid = l+r>>;
  127. if(L<=mid) Cov(i<<,l,mid,L,R,S,T);
  128. if(mid+<=R) Cov(i<<|,mid+,r,L,R,S,T);
  129. Renew(i);
  130. }
  131.  
  132. void Add(int i,int l,int r,int L,int R,double S,double T)
  133. {
  134. if(L<=l && r<=R)
  135. {
  136. Update(i,l,r,S,T);
  137. return;
  138. }
  139.  
  140. pushdown(i,l,r);
  141. int mid = l+r>>;
  142. if(L<=mid) Add(i<<,l,mid,L,R,S,T);
  143. if(mid+<=R) Add(i<<|,mid+,r,L,R,S,T);
  144. Renew(i);
  145. }
  146.  
  147. void Query(int i,int l,int r,int L,int R)
  148. {
  149. if(L<=l && r<=R)
  150. {
  151. res.x += Node[i].sumx; res.y += Node[i].sumy;
  152. res.xx += Node[i].sumxx; res.xy += Node[i].sumxy;
  153. return;
  154. }
  155.  
  156. pushdown(i,l,r);
  157. int mid = l+r>>;
  158. if(L<=mid) Query(i<<,l,mid,L,R);
  159. if(mid+<=R) Query(i<<|,mid+,r,L,R);
  160. }
  161.  
  162. int main()
  163. {
  164. for(int i=;i<=ONE-;i++) Sumsq[i] = Sumsq[i-] + (double)i*i;
  165.  
  166. n=get(); m=get();
  167. for(int i=;i<=n;i++) Vx[i]=get();
  168. for(int i=;i<=n;i++) Vy[i]=get();
  169. Build(,,n);
  170.  
  171. while(m--)
  172. {
  173. P = get(); L = get(); R = get();
  174. if(P == )
  175. {
  176. res.x = res.y = res.xx = res.xy = ;
  177. Query(,,n,L,R);
  178. double len = R-L+;
  179. double Avex = res.x / len;
  180. double Avey = res.y / len;
  181. printf("%.6lf\n", (res.xy - len * Avex * Avey) / (res.xx - len*Avex*Avex));
  182. }
  183. else
  184. {
  185. S = get(); T = get();
  186. if(P == ) Add(,,n, L,R,S,T);
  187. else Cov(,,n, L,R,S,T);
  188. }
  189. }
  190. }

【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. 2017-2018-2 20172323 『Java程序设计』课程 结对编程练习_四则运算

    结对编程的好丽友 - 20172323 王禹涵:中缀转后缀 - 20172314 方艺雯:后缀表达式的计算 - 20172305 谭鑫:中缀表达式的输出 需求分析 能随机生成由使用者确定的任意多道四则 ...

  2. 软件工程课堂作业(十一)——NABC分析

    一.团队开发项目:基于Android的重力感应的解锁APP 二.项目特点:区别于一般解锁软件用开机按钮开锁解锁,我们的重力解锁软件根据动作实现解锁,减少了开机按钮的使用频率,提高寿命. 三.NABC分 ...

  3. 展示github中的页面(Github Pages)

    一.创建一个仓库,名为"user_name.github.io"(此处user_name替换为你自己的github用户名),并在根目录下创建index.html,则该仓库下的所有h ...

  4. ALPHA-3

    前言 失心疯病源3 团队代码管理github 站立会议 队名:PMS 530雨勤(组长) 今天完成了那些任务 16:00~20:18 援助行人模块并确定最终框架,顺便不死心的又找了一波车辆检测的dem ...

  5. 201621123034 《Java程序设计》第5周学习总结

    作业05-继承.多态.抽象类与接口 1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 答:关键字:接口.继承.多态 1.2 尝试使用思维导图将这些关键词组织起来.注:思维导图一般 ...

  6. 【week2】Scrum中的站立会议

    Scrum站立会议    站立会议给我的第一印象就是站着开会,在经过我查阅资料之后,发现也是差不多的意思.学术一点的分析就是在Sprint开始后,团队将会在每个工作日特定时间举行一个简短会议,每次会议 ...

  7. Windows API封装:LoadLibrary/FreeLibrary

    LoadLibrary/LoadLibraryEx用来加载DLL到自己的进程空间,使用完用FreeLibrary释放,一般使用方式如下:    HINSTANCE hInstRich = ::Load ...

  8. Java 多线程 三种实现方式

    Java多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用ExecutorService.Callable.Future实现有返回结果的多线程.其中前两种方式线程执行完后都没 ...

  9. BZOJ 1911 特别行动队(斜率优化DP)

    应该可以看出这是个很normal的斜率优化式子.推出公式搞一搞即可. # include <cstdio> # include <cstring> # include < ...

  10. MyBatis之二级缓存

    二级缓存与一级缓存区别:二级缓存的范围更大,多个sqlSession可以共享一个UserMapper的二级缓存区域. 每一个mapper都有一个自己的二缓存区域(按namespace区分),两个map ...