【BZOJ4821】【SDOI2017】相关分析 [线段树]
相关分析
Time Limit: 10 Sec Memory Limit: 128 MB
[Submit][Status][Discuss]
Description
xx=Σx_i/(R-L+1)(L<=i<=R)
Input
Output
Sample Input
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.5000000000
-0.6153846154
HINT
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】相关分析 [线段树]的更多相关文章
- 【BZOJ4821】[Sdoi2017]相关分析 线段树
[BZOJ4821][Sdoi2017]相关分析 Description Frank对天文学非常感兴趣,他经常用望远镜看星星,同时记录下它们的信息,比如亮度.颜色等等,进而估算出星星的距离,半径等等. ...
- [Sdoi2017]相关分析 [线段树]
[Sdoi2017]相关分析 题意:沙茶线段树 md其实我考场上还剩一个多小时写了40分 其实当时写正解也可以吧1h也就写完了不过还要拍一下 正解代码比40分短2333 #include <io ...
- BZOJ 4821 [Sdoi2017]相关分析 ——线段树
打开题面,看到许多$\sum$ woc,好神啊,SDOI好强啊 然后展开之后,woc,SDOI好弱啊,怎么T3出个线段树裸题啊. 最后写代码的时候,woc,SDOI怎么出个这么码农的题啊,怎么调啊. ...
- 洛谷P3707 [SDOI2017]相关分析(线段树)
题目描述 Frank对天文学非常感兴趣,他经常用望远镜看星星,同时记录下它们的信息,比如亮度.颜色等等,进而估算出星星的距离,半径等等. Frank不仅喜欢观测,还喜欢分析观测到的数据.他经常分析两个 ...
- BZOJ 4821: [Sdoi2017]相关分析 线段树 + 卡精
考试的时候切掉了,然而卡精 + 有一个地方忘开 $long long$,完美挂掉 $50$pts. 把式子化简一下,然后直接拿线段树来维护即可. Code: // luogu-judger-enabl ...
- BZOJ.4821.[SDOI2017]相关分析(线段树)
BZOJ LOJ 洛谷 恶心的拆式子..然后就是要维护\(\sum x_i,\ \sum y_i,\ \sum x_iy_i,\ \sum x_i^2\). 操作三可以看成初始化一遍,然后同操作二. ...
- SDOI2017相关分析 线段树
题目 https://loj.ac/problem/2005 思路 \[ \sum_{L}^{R}{(x_i-x)^{2}} \] \[ \sum_{L}^{R}{(x_i^2-2*x_i*x+x^{ ...
- luogu3707 相关分析 (线段树)
把式子展开以后会发现,可以用线段树维护$x,y,x*y,x^2$分别的区间和 然后操作有区间加和区间修改 这个pushdown的时候,如果改和加的标记同时存在,那一定是先改再加,要不然加的标记已经被清 ...
- BZOJ4821 SDOI2017相关分析(线段树)
纯粹的码农题.维护x的和.y的和.xy的和.x2的和即可.可能会炸long long. #include<iostream> #include<cstdio> #include ...
随机推荐
- 算法与数据结构实验题 4.1 伊姐姐数字 game
★实验任务 伊姐姐热衷于各类数字游戏,24 点.2048.数独等轻轻松松毫无压力.一 日,可爱的小姐姐邀请伊姐姐一起玩一种简单的数字 game,游戏规则如下: 一开始桌上放着 n 张数字卡片,从左到右 ...
- object-oriented 第二次作业(2)
面向对象程序设计自学计划 由于我的英文实在是很差,所以我就没有去考虑看英文的课程视频.网络上的课程有很多,什么学校的也有,一开始我不知道该如何开始选择课程.感觉每个都还可以.后来在群里的看到别人推荐的 ...
- 《剑指offer》---字符串的全排列
本文算法使用python3实现 1.问题一 1.1 题目描述: 输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc ...
- <Effective C++>读书摘要--Resource Management<一>
1.除了内存资源以外,Other common resources include file descriptors, mutex locks, fonts and brushes in graphi ...
- 对alpha发布的总结技术随笔
对于今天的alpha发布,首先需要自我检讨,因为我们组没有展示作品.主要的原因还是我们投入的时间不足.我们的项目是约跑App,首先选择做安卓平台的东西,我们大家都需要熟悉新的开发软件Android S ...
- Linux文件传输FTP详解
ftp命令用来设置文件系统相关功能.ftp服务器在网上较为常见,Linux ftp命令的功能是用命令的方式来控制在本地机和远程机之间传送文件,这里详细介绍Linux ftp命令的一些经常使用的命令,相 ...
- 【bzoj5107】[CodePlus2017]找爸爸 dp
题目描述 给出两个基因串,你需要在其中插入任意个空格,使得两个串长度相同.如果两个串的某同一位置都是字母则获得某给定收益,对于每个串的每个长度为k的连续空格段要付出a(k-1)+b的损失.求最大净收益 ...
- 转:Lucene之计算相似度模型VSM(Vector Space Model) : tf-idf与交叉熵关系,cos余弦相似度
原文:http://blog.csdn.net/zhangbinfly/article/details/7734118 最近想学习下Lucene ,以前运行的Demo就感觉很神奇,什么原理呢,尤其是查 ...
- 【题解】CF#833 B-The Bakery
一个非常明显的 \(nk\) dp 状态 \(f[i][k]\) 表示以 \(i\) 为第 \(k\) 段的最后一个元素时所能获得的最大代价.转移的时候枚举上一段的最后一个元素 \(j\)更新状态即可 ...
- POJ3304:Segments——题解
http://poj.org/problem?id=3304 题目大意:给n条线段,求是否存在一条直线,将所有线段投影到上面,使得所有投影至少交于一点. ——————————————————————— ...