【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 ...
随机推荐
- 2017-2018-2 20172323 『Java程序设计』课程 结对编程练习_四则运算
结对编程的好丽友 - 20172323 王禹涵:中缀转后缀 - 20172314 方艺雯:后缀表达式的计算 - 20172305 谭鑫:中缀表达式的输出 需求分析 能随机生成由使用者确定的任意多道四则 ...
- 软件工程课堂作业(十一)——NABC分析
一.团队开发项目:基于Android的重力感应的解锁APP 二.项目特点:区别于一般解锁软件用开机按钮开锁解锁,我们的重力解锁软件根据动作实现解锁,减少了开机按钮的使用频率,提高寿命. 三.NABC分 ...
- 展示github中的页面(Github Pages)
一.创建一个仓库,名为"user_name.github.io"(此处user_name替换为你自己的github用户名),并在根目录下创建index.html,则该仓库下的所有h ...
- ALPHA-3
前言 失心疯病源3 团队代码管理github 站立会议 队名:PMS 530雨勤(组长) 今天完成了那些任务 16:00~20:18 援助行人模块并确定最终框架,顺便不死心的又找了一波车辆检测的dem ...
- 201621123034 《Java程序设计》第5周学习总结
作业05-继承.多态.抽象类与接口 1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 答:关键字:接口.继承.多态 1.2 尝试使用思维导图将这些关键词组织起来.注:思维导图一般 ...
- 【week2】Scrum中的站立会议
Scrum站立会议 站立会议给我的第一印象就是站着开会,在经过我查阅资料之后,发现也是差不多的意思.学术一点的分析就是在Sprint开始后,团队将会在每个工作日特定时间举行一个简短会议,每次会议 ...
- Windows API封装:LoadLibrary/FreeLibrary
LoadLibrary/LoadLibraryEx用来加载DLL到自己的进程空间,使用完用FreeLibrary释放,一般使用方式如下: HINSTANCE hInstRich = ::Load ...
- Java 多线程 三种实现方式
Java多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用ExecutorService.Callable.Future实现有返回结果的多线程.其中前两种方式线程执行完后都没 ...
- BZOJ 1911 特别行动队(斜率优化DP)
应该可以看出这是个很normal的斜率优化式子.推出公式搞一搞即可. # include <cstdio> # include <cstring> # include < ...
- MyBatis之二级缓存
二级缓存与一级缓存区别:二级缓存的范围更大,多个sqlSession可以共享一个UserMapper的二级缓存区域. 每一个mapper都有一个自己的二缓存区域(按namespace区分),两个map ...