bzoj4821
线段树
这题真是无聊
把式子拆开,然后可知维护xi,yi,xi^2,xi*yi,重点在于标记下传,当我们进行2号操作时,直接累加进答案和标记即可,进行3号操作时,update时先把自己这层赋值成要改变的值,再清空这层2号标记,每次pushdown把这层的下一层的标记清空,因为下一层被覆盖了,pushdown先执行3号标记,再执行2号标记,因为存在的2号标记肯定在3号标记后打的,否则肯定会被清空,所以2号标记应该在三号标记后。
而下一层的2号标记肯定是在三号标记之前打的,因为标记已经下传。
#include<bits/stdc++.h>
using namespace std;
typedef double ld;
const int N = ;
int n, m;
ld x[N], y[N];
struct node {
double sumx, sumy, sumxx, sumxy;
node(ld sumx = , ld sumy = , ld sumxx = , ld sumxy = ) : sumx(sumx), sumy(sumy), sumxx(sumxx), sumxy(sumxy) {}
void print()
{
printf("sumx=%.10f sumy=%.10f sumxx=%.10f sumxy=%.10f\n", sumx, sumy, sumxx, sumxy);
}
};
struct seg {
node tree[N << ];
ld tagx2[N << ], tagy2[N << ], tagx3[N << ], tagy3[N << ];
bool can1[N << ], can2[N << ];
ld calc(ld x)
{
return (ld)x * (ld)(x + ) * (ld)( * x + ) / ;
}
void pushdown(int o, int l, int r)
{
int mid = (l + r) >> ;
if(can1[o])
{
tree[o << ].sumx = (ld)(mid - l + ) * tagx3[o] + (ld)(mid + l) * (ld)(mid - l + ) / 2.0;
tree[o << | ].sumx = (ld)(r - mid) * tagx3[o] + (ld)(r + mid + ) * (ld)(r - mid) / 2.0;
tree[o << ].sumy = (ld)(mid - l + ) * tagy3[o] + (ld)(mid + l) * (ld)(mid - l + ) / 2.0;
tree[o << | ].sumy = (ld)(r - mid) * tagy3[o] + (ld)(r + mid + ) * (ld)(r - mid) / 2.0;
tree[o << ].sumxx = calc(tagx3[o] + mid) - calc(tagx3[o] + l - );
tree[o << | ].sumxx = calc(tagx3[o] + r) - calc(tagx3[o] + mid);
tree[o << ].sumxy = (ld)(mid - l + ) * tagx3[o] * tagy3[o] + (ld)(tagx3[o] + tagy3[o]) * (ld)(mid + l) * (ld)(mid - l + ) / 2.0 + calc(mid) - calc(l - );
tree[o << | ].sumxy = (ld)(r - mid) * tagx3[o] * tagy3[o] + (ld)(tagx3[o] + tagy3[o]) * (ld)(r + mid + ) * (ld)(r - mid) / 2.0 + calc(r) - calc(mid);
tagx3[o << ] = tagx3[o << | ] = tagx3[o];
tagy3[o << ] = tagy3[o << | ] = tagy3[o];
tagx3[o] = tagy3[o] = ;
tagx2[o << ] = tagx2[o << | ] = tagy2[o << ] = tagy2[o << | ] = ;
can2[o << ] = can2[o << | ] = ;
can1[o << ] = can1[o << | ] = can1[o];
can1[o] = ;
}
if(can2[o])
{
tree[o << ].sumxx += 2.0 * tree[o << ].sumx * tagx2[o] + (ld)(mid - l + ) * tagx2[o] * tagx2[o];
tree[o << | ].sumxx += 2.0 * tree[o << | ].sumx * tagx2[o] + (ld)(r - mid) * tagx2[o] * tagx2[o];
tree[o << ].sumxy += tree[o << ].sumx * tagy2[o] + tree[o << ].sumy * tagx2[o] + (ld)(mid - l + ) * tagx2[o] * tagy2[o];
tree[o << | ].sumxy += tree[o << | ].sumx * tagy2[o] + tree[o << | ].sumy * tagx2[o] + (ld)(r - mid) * tagx2[o] * tagy2[o];
tree[o << ].sumx += tagx2[o] * (ld)(mid - l + );
tree[o << | ].sumx += tagx2[o] * (ld)(r - mid);
tree[o << ].sumy += tagy2[o] * (ld)(mid - l + );
tree[o << | ].sumy += tagy2[o] * (ld)(r - mid);
tagx2[o << ] += tagx2[o];
tagx2[o << | ] += tagx2[o];
tagy2[o << ] += tagy2[o];
tagy2[o << | ] += tagy2[o];
tagx2[o] = ;
tagy2[o] = ;
can2[o << ] = can2[o << | ] = can2[o];
can2[o] = ;
}
}
node merge(node B, node C)
{
node A;
A.sumx = B.sumx + C.sumx;
A.sumy = B.sumy + C.sumy;
A.sumxx = B.sumxx + C.sumxx;
A.sumxy = B.sumxy + C.sumxy;
return A;
}
void build(int l, int r, int o)
{
if(l == r)
{
tree[o] = node(x[l], y[l], x[l] * x[l], x[l] * y[l]);
return;
}
int mid = (l + r) >> ;
build(l, mid, o << );
build(mid + , r, o << | );
tree[o] = merge(tree[o << ], tree[o << | ]);
}
node query(int l, int r, int o, int a, int b)
{
if(l > b || r < a) return tree[];
if(l >= a && r <= b) return tree[o];
int mid = (l + r) >> ;
pushdown(o, l, r);
node tx = query(l, mid, o << , a, b), ty = query(mid + , r, o << | , a, b);
return merge(tx, ty);
}
void update2(int l, int r, int o, int a, int b, ld s, ld t)
{
if(l > b || r < a) return;
if(l >= a && r <= b)
{
tagx2[o] += s;
tagy2[o] += t;
tree[o].sumxx += 2.0 * tree[o].sumx * s + (ld)(r - l + ) * s * s;
tree[o].sumxy += t * tree[o].sumx + s * tree[o].sumy + (ld)(r - l + ) * s * t;
tree[o].sumx += (ld)(r - l + ) * s;
tree[o].sumy += (ld)(r - l + ) * t;
can2[o] = ;
return;
}
pushdown(o, l, r);
int mid = (l + r) >> ;
update2(l, mid, o << , a, b, s, t);
update2(mid + , r, o << | , a, b, s, t);
tree[o] = merge(tree[o << ], tree[o << | ]);
}
void update3(int l, int r, int o, int a, int b, ld s, ld t)
{
if(l > b || r < a) return;
if(l >= a && r <= b)
{
tagx3[o] = s;
tagy3[o] = t;
tagx2[o] = tagy2[o] = ;
tree[o].sumx = (ld)(r - l + ) * s + (ld)(l + r) * (ld)(r - l + ) / 2.0;
tree[o].sumy = (ld)(r - l + ) * t + (ld)(l + r) * (ld)(r - l + ) / 2.0;
tree[o].sumxx = calc(s + r) - calc(s + l - );
tree[o].sumxy = (ld)(r - l + ) * s * t + ((ld)(l + r) * (ld)(r - l + ) / 2.0) * (ld)(s + t) + calc(r) - calc(l - );
can1[o] = ;
can2[o] = ;
return;
}
pushdown(o, l, r);
int mid = (l + r) >> ;
update3(l, mid, o << , a, b, s, t);
update3(mid + , r, o << | , a, b, s, t);
tree[o] = merge(tree[o << ], tree[o << | ]);
}
} t;
int main()
{
scanf("%d%d", &n, &m);
for(int i = ; i <= n; ++i)
scanf("%lf", &x[i]);
for(int i = ; i <= n; ++i)
scanf("%lf", &y[i]);
t.build(, n, );
for(int i = ; i <= m; ++i)
{
int opt, l, r;
ld S, T;
scanf("%d", &opt);
if(opt == )
{
scanf("%d%d", &l, &r);
node o = t.query(, n, , l, r);
ld ox = o.sumx / (ld)(r - l + ), oy = o.sumy / (ld)(r - l + );
ld up = ((ld)(r - l + ) * o.sumxy - o.sumx * o.sumy), down = ((ld)(r - l + ) * o.sumxx - o.sumx * o.sumx), ans = up / down;
printf("%.10f\n", ans);
}
if(opt == )
{
scanf("%d%d%lf%lf", &l, &r, &S, &T);
t.update2(, n, , l, r, S, T);
}
if(opt == )
{
scanf("%d%d%lf%lf", &l, &r, &S, &T);
t.update3(, n, , l, r, S, T);
}
}
return ;
}
bzoj4821的更多相关文章
- 【BZOJ4821】[SDOI2017]相关分析(线段树)
[BZOJ4821][SDOI2017]相关分析(线段树) 题面 BZOJ 洛谷 题解 看看询问要求的东西是什么.把所有的括号拆开,不难发现要求的就是\(\sum x,\sum y,\sum xy,\ ...
- BZOJ4821 SDOI2017相关分析(线段树)
纯粹的码农题.维护x的和.y的和.xy的和.x2的和即可.可能会炸long long. #include<iostream> #include<cstdio> #include ...
- 【BZOJ4821】[Sdoi2017]相关分析 线段树
[BZOJ4821][Sdoi2017]相关分析 Description Frank对天文学非常感兴趣,他经常用望远镜看星星,同时记录下它们的信息,比如亮度.颜色等等,进而估算出星星的距离,半径等等. ...
- [bzoj4821][Sdoi2017]相关分析
来自FallDream的博客,未经允许,请勿转载,谢谢. Frank对天文学非常感兴趣,他经常用望远镜看星星,同时记录下它们的信息,比如亮度.颜色等等,进而估算出星星的距离,半径等等.Frank不仅喜 ...
- 【BZOJ4821】【SDOI2017】相关分析 [线段树]
相关分析 Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description Frank对天文学非常感兴趣,他经 ...
- bzoj4821 && luogu3707 SDOI2017相关分析(线段树,数学)
题目大意 给定n个元素的数列,每一个元素有x和y两种元素,现在有三种操作: \(1\ L\ R\) 设\(xx\)为\([l,r]\)的元素的\(x_i\)的平均值,\(yy\)同理 求 \(\fra ...
- SDOI2017第一轮
本蒟蒻表示终于$AC$了$SDOI2017\text{第一轮}$! 兴奋! 附上各个题的题解: $DAT1$: $T1$: BZOJ4816: [Sdoi2017]数字表格 $T2$: BZOJ481 ...
- SDOI2017 Round1 Day2 题解
T2好厉害啊……AK不了啦……不过要是SCOI考这套题就好了240保底. BZOJ4819 新生舞会 模板题,分数规划+二分图最大权匹配. 费用流跑得过,可以不用KM. UPD:分数规划用迭代跑得飞快 ...
随机推荐
- rename命令中正则表达式的使用
rename命令用字符串替换的方式批量改变文件名. 格式如下: rename 原字符串 目标字符串 文件(列表) 原字符串:将文件名需要替换的字符串: 目标字符串:将文件名中含有的原字符替换成目标 ...
- 网络编程 - join及守护线程
一.Join实例(join理解为等待)import threading,timedef run(n): time.sleep(3) print ("task",n)start = ...
- Vue.js 模板语法
本章节将详细介绍 Vue.js 模板语法,如果对 HTML +Css +JavaScript 有一定的了解,学习起来将信手拈来. Vue.js 使用了基于 HTML 的模版语法,允许开发者声明式地将 ...
- STL源码分析之第二级配置器
前言 第一级是直接调用malloc分配空间, 调用free释放空间, 第二级三就是建立一个内存池, 小于128字节的申请都直接在内存池申请, 不直接调用malloc和free. 本节分析第二级空间配置 ...
- python3.x Day1 菜单程序练习
三级菜单: 1. 运行程序输出第一级菜单 2. 选择一级菜单某项,输出二级菜单,同理输出三级菜单 3. 菜单数据保存在文件中 4. 让用户选择是否要退出 5. 有返回上一级菜单的功能 类定义:menu ...
- scrapy 按顺序抓取text内容
需求:获得如下li.clearfix 下的所有text,并且按顺序输出 1. x.css('div.reply-doc h4 a::text').extract(); 2. x.css('div.r ...
- 多校1007 Naive Operations
>>点击进入原题测试<< 思路:好像是第一次这么印象深刻的写线段树,说实话,这个题确实很有意思,值得学习. 看了大神讲解视频,但是自己写的还是超时了. 参考来自 https:/ ...
- Android layer-list:联合shape(2)
Android layer-list:联合shape(2) 附录文章3简单说明了Android layer-list的用法,现在把Android layer-list联合shape做出一些特殊的 ...
- 使用spring框架提供的处理中文乱码的过滤器
在web-xml中直接写上spring框架提供的过滤器即可 <filter> <filter-name>encoding</filter-name> <fil ...
- project处理 InteropServices.COMException 异常
project文件无法上传,在上传中的hangfire出现了这个异常 System.Runtime.InteropServices.COMException 这个是因为website的权限是IUser ...