【BZOJ4821】[Sdoi2017]相关分析 线段树
【BZOJ4821】[Sdoi2017]相关分析
Description
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
题解:显然直接用线段树,需要维护一下几个东西:x之和,x^2之和,y之和,x*y之和。并且同时还要支持区间赋值和区间加。没有细节,就是讨论。
这里只说如何处理x*y吧,对于区间加,$\sum(x+v)(y+v)=\sum x*y+v*\sum (x+y)+v*v*n$。对于区间赋值,$\sum\limits_{i=1}^n(a+i)(b+i)=\sum\limits_{i=1}^nab+(a+b)\sum\limits_{i=1}^ni+\sum\limits_{i=1}^ni^2$。
#include <cstdio>
#include <cstring>
#include <iostream>
#define ls t<<1
#define rs t<<1|1
#define S2(_) ((_)*((_)+1)*(2*(_)+1)/6)
using namespace std;
typedef double db;
const int maxn=100010;
int n,m;
db X,Y,XX,YY,XY;
db x[maxn<<2],y[maxn<<2],xx[maxn<<2],yy[maxn<<2],xy[maxn<<2],xa[maxn],ya[maxn],sx[maxn<<2],sy[maxn<<2];
db tx[maxn<<2],ty[maxn<<2];
db ans1,ans2,_X,_Y;
inline void pushup(int t)
{
x[t]=x[ls]+x[rs],y[t]=y[ls]+y[rs],xx[t]=xx[ls]+xx[rs],yy[t]=yy[ls]+yy[rs],xy[t]=xy[ls]+xy[rs];
}
inline void pds(db siz,int t,db a,db b)
{
xx[t]+=2*a*x[t]+a*a*siz,yy[t]=2*b*y[t]+b*b*siz,xy[t]=xy[t]+b*x[t]+a*y[t]+a*b*siz,x[t]+=a*siz,y[t]+=b*siz;
if(tx[t]!=1e15) tx[t]+=a,ty[t]+=b;
else sx[t]+=a,sy[t]+=b;
}
inline void pdt(int l,int r,int t,db a,db b)
{
db siz=r-l+1;
x[t]=(a+l+a+r)*siz/2,y[t]=(b+l+b+r)*siz/2,xx[t]=S2(a+r)-S2(a+l-1),yy[t]=S2(b+r)-S2(b+l-1);
xy[t]=(a+l-1)*(b+l-1)*siz+(a+l-1+b+l-1)*siz*(siz+1)/2+S2(siz);
sx[t]=sy[t]=0,tx[t]=a,ty[t]=b;
}
inline void pushdown(int l,int r,int t)
{
int mid=(l+r)>>1;
if(sx[t]||sy[t]) pds(mid-l+1,ls,sx[t],sy[t]),pds(r-mid,rs,sx[t],sy[t]),sx[t]=sy[t]=0;
if(tx[t]!=1e15) pdt(l,mid,ls,tx[t],ty[t]),pdt(mid+1,r,rs,tx[t],ty[t]),tx[t]=ty[t]=1e15;
}
void build(int l,int r,int t)
{
tx[t]=ty[t]=1e15;
if(l==r)
{
x[t]=xa[l],y[t]=ya[l],xx[t]=x[t]*x[t],yy[t]=y[t]*y[t],xy[t]=x[t]*y[t];
return ;
}
int mid=(l+r)>>1;
build(l,mid,ls),build(mid+1,r,rs);
pushup(t);
}
void ups(int l,int r,int t,int a,int b,db A,db B)
{
if(a<=l&&r<=b)
{
pds(r-l+1,t,A,B);
return ;
}
pushdown(l,r,t);
int mid=(l+r)>>1;
if(a<=mid) ups(l,mid,ls,a,b,A,B);
if(b>mid) ups(mid+1,r,rs,a,b,A,B);
pushup(t);
}
void upt(int l,int r,int t,int a,int b,db A,db B)
{
if(a<=l&&r<=b)
{
pdt(l,r,t,A,B);
return ;
}
pushdown(l,r,t);
int mid=(l+r)>>1;
if(a<=mid) upt(l,mid,ls,a,b,A,B);
if(b>mid) upt(mid+1,r,rs,a,b,A,B);
pushup(t);
}
void query(int l,int r,int t,int a,int b)
{
if(a<=l&&r<=b)
{
X+=x[t],Y+=y[t],XX+=xx[t],YY+=yy[t],XY+=xy[t];
return ;
}
pushdown(l,r,t);
int mid=(l+r)>>1;
if(a<=mid) query(l,mid,ls,a,b);
if(b>mid) query(mid+1,r,rs,a,b);
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int main()
{
n=rd(),m=rd();
int i,a,b,c,d,op;
for(i=1;i<=n;i++) xa[i]=rd();
for(i=1;i<=n;i++) ya[i]=rd();
build(1,n,1);
for(i=1;i<=m;i++)
{
op=rd(),a=rd(),b=rd();
if(op==1)
{
c=b-a+1,X=Y=XX=YY=XY=0,query(1,n,1,a,b),_X=(db)X/c,_Y=(db)Y/c;
ans1=XY-_X*Y-_Y*X+_X*_Y*c,ans2=XX-2*_X*X+_X*_X*c;
printf("%.10lf\n",ans1/ans2);
}
if(op==2) c=rd(),d=rd(),ups(1,n,1,a,b,c,d);
if(op==3) c=rd(),d=rd(),upt(1,n,1,a,b,c,d);
}
return 0;
}
【BZOJ4821】[Sdoi2017]相关分析 线段树的更多相关文章
- [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^{ ...
- 【BZOJ4821】【SDOI2017】相关分析 [线段树]
相关分析 Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description Frank对天文学非常感兴趣,他经 ...
- luogu3707 相关分析 (线段树)
把式子展开以后会发现,可以用线段树维护$x,y,x*y,x^2$分别的区间和 然后操作有区间加和区间修改 这个pushdown的时候,如果改和加的标记同时存在,那一定是先改再加,要不然加的标记已经被清 ...
- BZOJ4821 SDOI2017相关分析(线段树)
纯粹的码农题.维护x的和.y的和.xy的和.x2的和即可.可能会炸long long. #include<iostream> #include<cstdio> #include ...
随机推荐
- django迁移model到别的app中
举例: 移动 users.AccessKey 到 authentication.AccessKey中 1. 移动models到新的app中 $ mv users/models/access_key.p ...
- [Unity3D]UI方案及制作细节(NGUI/EZGUI/原生UI系统)
转载请留下本文原始链接,谢谢.本文会不定期更新维护,最近更新于2013.09.17. http://blog.sina.com.cn/s/blog_5b6cb9500101bplv.html ...
- lodash round
_.round(number, [precision=0]) 根据 precision 四舍五入 number. _.round(4.006); // => 4 _.round(4.006, 2 ...
- 删除LINUX更新后多余的内核
删除LINUX更新后多余的内核 本人使用的时fredoa 21 之前为了搞网卡驱动不知不觉升级了几次系统,每次启动后都有好几个内核让我选,真的非常头疼阿,尤其像博主这样的有点强迫的人,看着就心烦,所以 ...
- java之static关键字
介绍: 1.在类中,用static声明的成员变量为静态成员变量,它为该类的公用变量,在第一次使用时被初始化,对于该类的所有对象来说,static成员变量只有一份. 2.用static声明的方法为静态方 ...
- 可以打开QQ,但打不开网页的DNS服务器设置问题
方法二: IE->设置->连接->局域网设置
- CentOS7下利用init.d启动脚本实现tomcat开机自启动
在之前的博文中已经对CentOS7下通过tomcat进行WEB系统的发布进行了介绍,今天将利用init.d启动脚本,将服务脚本加入到开机启动服务队列,实现tomcat服务的开机启动. 1. 环境准备 ...
- linux下 目录(扩容)挂载磁盘
1.常用命令 查看硬盘的分区 #sudo fdisk -l 查看IDE硬盘信息 #sudo hdparm -i /dev/hda 查看STAT硬盘信息 #sudo hdparm -I /dev/sda ...
- 辛星跟您玩转vim第二节之用vim命令移动光标
首先值得一提的是,我的vim教程pdf版本号已经写完了,大家能够去下载.这里是csdn的下载地址:csdn下载.假设左边的下载地址挂掉了,也能够自行在浏览器以下输入例如以下地址进行下载:http:// ...
- 234. Palindrome Linked List【easy】
234. Palindrome Linked List[easy] Given a singly linked list, determine if it is a palindrome. Follo ...