●BZOJ 4821 [Sdoi2017]相关分析
题链:
http://www.lydsy.com/JudgeOnline/problem.php?id=4821
题解:
线段树
是真的恶心,(也许是我的方法麻烦了一些吧)
首先那个式子可以做如下化简:
${a}=\frac {\sum{(}{x}_{i}-\overline{x}{)}{(}{y}_{i}-\overline{y}{)} } {\sum{(}{x}_{i}-\overline{x}{)}{(}{x}_{i}-\overline{x}{)} }$
$\;\;=\frac{{(}\sum{{x}_{i}{y}_{i}}{)}-{n}\overline{x}\overline{y}} {{(}\sum{{x}_{i}{x}_{i}}{)}-{n}\overline{x}\overline{x}}$
然后可以发现,记录区间内的:
x的和(sx),y的和(sy),x*y的和(sxy),x*x的和(sxx),再来两个lazy标记表示区间x,y增量。
以上的东西用线段树维护就可以解决掉第一个和第二个操作。
但是第三个操作怎么办呢?
我们把每个 xi = i + _xi,yi = i + _yi
然后用 _xi,_yi 去建立上述线段树,及维护和上面相同的东西:
_x的和(_sx),_y的和(_sy),_x*_y的和(_sxy),_x*_x的和(_sxx),再来两个lazy标记表示区间x,y增量。
这样就可以同样以区间修改的方式完成第三个操作。
但是接下来又来了一个问题:
对于一个询问,如何从维护得到的四元组(_sx,_sy,_sxy,_sxx),
得到用于求出答案的四元组(sx,sy,sxy,sxx)
看看如下式子:(用 ' 代替 _)
${x}_{i}\times{y}_{i}$
$={{(}{x'}_{i}+{i}{)}}\times{{(}{y'}_{i}+{i}{)}}$
$={x'_iy'_i}+{2i}{(}{x'_i+y'_i}{)}+{i^2}$
所以
$\begin{align}{sxy}&={sxy'}\\&+{2(\;\;}{{i(}x'_i+y'_i{)}}+{{{(}i+1{)}(}x'_{i+1}+y'_{i+1}{)}}+{{{(}i+2{)}(}x'_{i+2}+y'_{i+2}{)}}+\cdots{)}\\&+{(}i^2+{{(}i+1{)}}^2+{{(}i+2{)}}^2+\cdots{)}\end{align}$
所以只需再维护一些东西用于计算上面式子的中间项和末尾项即可。
即对每个区间 l~r 维护:
_sufxx:${l}\times{(}{x'}_{l}+{x'}_{l}{)} +{(l+1)}\times{(}{x'}_{l+1}+{x'}_{l+1}{)} +\cdots+ {r}\times{(}{x'}_{r}+{x'}_{r}{)}$
_sufxy:${l}\times{(}{x'}_{l}+{y'}_{l}{)} +{(l+1)}\times{(}{x'}_{l+1}+{y'}_{l+1}{)} +\cdots+ {r}\times{(}{x'}_{r}+{y'}_{r}{)}$
再预处理一个数组 ${pi2[i]}=1^2+2^2+3^2+\cdots+i^2$
然后就可以搞出四元组 (sx,sy,sxy,sxx),进而得出答案。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXN 100500
#define filein(x) freopen(#x".out","r",stdin)
#define fileout(x) freopen(#x".out","w",stdout)
using namespace std;
double pi2[MAXN];
int x[MAXN],y[MAXN];
struct Info{
double _x,_y,_xy,_xx,_sufxy,_sufxx,_s,_t; int len;
void Clear(){
_x=_y=_xy=_xx=_sufxy=_sufxx=_s=_t=0;
}
void Modify(double s,double t,int type){
if(type==2) Clear();
_xx+=_x*s+_x*s+s*s*len;
_xy+=_x*t+_y*s+s*t*len;
_sufxx+=(s+s)*(1.0+(1+len-1))*len/2;
_sufxy+=(s+t)*(1.0+(1+len-1))*len/2;
_x+=s*len; _y+=t*len;
_s+=s; _t+=t;
}
void Update(const Info &ls,const Info &rs){
_x=ls._x+rs._x; _y=ls._y+rs._y;
_xx=ls._xx+rs._xx; _xy=ls._xy+rs._xy;
_sufxx=ls._sufxx+rs._sufxx+(rs._x+rs._x)*ls.len;
_sufxy=ls._sufxy+rs._sufxy+(rs._x+rs._y)*ls.len;
}
double Calc(const int &l){
double X,Y,XX,XY;
X=_x+(1.0*l+(l+len-1))*len/2; X=X/len;
Y=_y+(1.0*l+(l+len-1))*len/2; Y=Y/len;
XX=_xx+(_sufxx+1.0*(l-1)*(_x+_x))+(pi2[l+len-1]-pi2[l-1]);
XY=_xy+(_sufxy+1.0*(l-1)*(_x+_y))+(pi2[l+len-1]-pi2[l-1]);
return (XY-X*Y*len)/(XX-X*X*len);
}
};
struct SGT{
#define ls lson[u]
#define rs rson[u]
#define alen ((r<ar?r:ar)-(l>al?l:al)+1)
int lson[MAXN*2],rson[MAXN*2],lazy[MAXN*2],sz,rt;
Info nd[MAXN*2];
void pushup(Info &ndu,const Info &ndls,const Info &ndrs){
ndu.Update(ndls,ndrs);
}
void pushdown(int u){
nd[ls].Modify(nd[u]._s,nd[u]._t,lazy[u]),
nd[rs].Modify(nd[u]._s,nd[u]._t,lazy[u]);
lazy[ls]=max(lazy[ls],lazy[u]);
lazy[rs]=max(lazy[rs],lazy[u]);
lazy[u]=nd[u]._s=nd[u]._t=0;
}
void build(int &u,int l,int r){
u=++sz; nd[u].len=r-l+1;
if(l==r){
nd[u].Modify(x[l],y[l],2);
return;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
pushup(nd[u],nd[ls],nd[rs]);
}
void Modify(int u,int l,int r,int al,int ar,double s,double t,int type){
if(al<=l&&r<=ar){
lazy[u]=max(lazy[u],type);
nd[u].Modify(s,t,type);
return;
}
int mid=(l+r)>>1;
if(lazy[u]) pushdown(u);
if(al<=mid) Modify(ls,l,mid,al,ar,s,t,type);
if(mid<ar) Modify(rs,mid+1,r,al,ar,s,t,type);
pushup(nd[u],nd[ls],nd[rs]);
}
Info Query(int u,int l,int r,int al,int ar){
if(al<=l&&r<=ar) return nd[u];
int mid=(l+r)>>1; Info ret,lret,rret;
ret.Clear(); lret.Clear(); rret.Clear();
ret.len=alen; lret.len=0; rret.len=0;
if(lazy[u]) pushdown(u);
if(al<=mid) lret=Query(ls,l,mid,al,ar);
if(mid<ar) rret=Query(rs,mid+1,r,al,ar);
pushup(ret,lret,rret);
return ret;
}
#undef ls
#undef rs
#undef alen
}T;
int N,M;
void read(int &X){
static int f; static char ch;
scanf("%d",&X); return;
X=0; f=1; ch=getchar();
while(ch<'0'||'9'<ch){if(ch=='-') f=-1;ch=getchar();}
while('0'<=ch&&ch<='9'){X=X*10+ch-'0'; ch=getchar();}
X=X*f;
}
int main(){
read(N); read(M);
for(int i=1;i<=N;i++) pi2[i]=pi2[i-1]+1.0*i*i;
for(int i=1;i<=N;i++) read(x[i]),x[i]-=i;
for(int i=1;i<=N;i++) read(y[i]),y[i]-=i;
T.build(T.rt,1,N);
Info ret; int c,l,r,s,t;
for(int i=1;i<=M;i++){
read(c); read(l); read(r);
if(c==1){
ret=T.Query(T.rt,1,N,l,r);
printf("%.10lf\n",ret.Calc(l));
}
else{
read(s); read(t);
T.Modify(T.rt,1,N,l,r,s,t,c-1);
}
}
return 0;
}
●BZOJ 4821 [Sdoi2017]相关分析的更多相关文章
- (WA)BZOJ 4821: [Sdoi2017]相关分析
二次联通门 : BZOJ 4821: [Sdoi2017]相关分析 2017.8.23 Updata 妈妈!!这道题卡我!!!就是不然我过!!!!! #include <cstdio> # ...
- BZOJ.4821.[SDOI2017]相关分析(线段树)
BZOJ LOJ 洛谷 恶心的拆式子..然后就是要维护\(\sum x_i,\ \sum y_i,\ \sum x_iy_i,\ \sum x_i^2\). 操作三可以看成初始化一遍,然后同操作二. ...
- bzoj 4821 [Sdoi2017]相关分析
题面 https://www.lydsy.com/JudgeOnline/problem.php?id=4821 题解 做法显然 就是维护一颗线段树 里面装4个东西 区间x的和 区间y的和 区间$x^ ...
- BZOJ 4821 [Sdoi2017]相关分析 ——线段树
打开题面,看到许多$\sum$ woc,好神啊,SDOI好强啊 然后展开之后,woc,SDOI好弱啊,怎么T3出个线段树裸题啊. 最后写代码的时候,woc,SDOI怎么出个这么码农的题啊,怎么调啊. ...
- BZOJ 4821: [Sdoi2017]相关分析 线段树 + 卡精
考试的时候切掉了,然而卡精 + 有一个地方忘开 $long long$,完美挂掉 $50$pts. 把式子化简一下,然后直接拿线段树来维护即可. Code: // luogu-judger-enabl ...
- 4821: [Sdoi2017]相关分析
4821: [Sdoi2017]相关分析 链接 分析: 大力拆式子,化简,然后线段树.注意精度问题与爆longlong问题. 代码: #include<cstdio> #include&l ...
- BZOJ4817 SDOI2017 相关分析
4821: [Sdoi2017]相关分析 Time Limit: 10 Sec Memory Limit: 128 MBSec Special Judge Description Frank对天文 ...
- 【BZOJ4821】[SDOI2017]相关分析(线段树)
[BZOJ4821][SDOI2017]相关分析(线段树) 题面 BZOJ 洛谷 题解 看看询问要求的东西是什么.把所有的括号拆开,不难发现要求的就是\(\sum x,\sum y,\sum xy,\ ...
- [Sdoi2017]相关分析 [线段树]
[Sdoi2017]相关分析 题意:沙茶线段树 md其实我考场上还剩一个多小时写了40分 其实当时写正解也可以吧1h也就写完了不过还要拍一下 正解代码比40分短2333 #include <io ...
随机推荐
- 国内maven仓库地址 || 某个pom或者jar找不到的解决方法
解决方法 建议在maven仓库中新建settings.xml,然后把如下内容粘贴进去即可.也可以找到maven的安装目录中的conf/settings.xml,把如下的mirrors节复制到对应部分. ...
- Unity使用脚本进行批量动态加载贴图
先描述一下我正在做的这个项目,是跑酷类音游. 那么跑酷类音游在绘制跑道上的时候,就要考虑不同的砖块显示问题.假设我有了一个节奏列表,那么我们怎么将不同的贴图贴到不同的砖块上去呢? 我花了好几个小时才搞 ...
- MapReduce工作机制——Word Count实例(一)
MapReduce工作机制--Word Count实例(一) MapReduce的思想是分布式计算,也就是分而治之,并行计算提高速度. 编程思想 首先,要将数据抽象为键值对的形式,map函数输入键值对 ...
- gdb-peda调试总汇
gdb-peda调试总汇 break *0x400100 (b main):在 0x400100 处下断点 tb一次性断点 info b:查看断点信息 delete [number]:删除断点 wat ...
- SQL字符串操作汇总
SQL字符串操作汇总 --将字符串中从某个字符开始截取一段字符,然后将另外一个字符串插入此处 select stuff('hello,world!',4,4,'****') --返回值hel*** ...
- mysql中text数据类型
有个小问题记录下: 需要从第三方api接口获取数据,返回的数据的长度不定,设计表的时候设计成了varchar(256):结果存数据的时候提示表字段长度不够. 一直从300改到500,600,700都一 ...
- python Django知识点总结
python Django知识点总结 一.Django创建项目: CMD 终端:Django_admin startproject sitename(文件名) 其他常用命令: 其他常用命令: 通过类创 ...
- Python scrapy框架
Scrapy Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了页面抓取 (更确切来说, 网络抓取 )所设 ...
- POJ-2349 Arctic Network---MST的第m长的边
题目链接: https://vjudge.net/problem/POJ-2349 题目大意: 要在n个节点之间建立通信网络,其中m个节点可以用卫星直接连接,剩下的节点都要用线路连接,求剩下这些线路中 ...
- C#之不安全代码
MSDN:"尽管实际上对 C 或 C++ 中的每种指针类型构造,C# 都设置了与之对应的引用类型,但仍然会有一些场合需要访问指针类型.例如,当需要与基础操作系统进行交互.访问内存映射设备,或 ...