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:分数规划用迭代跑得飞快 ...
随机推荐
- 09C语言指针
C语言指针 地址 地址就是数据元素在内存中的位置表示: &变量名 #include <stdio.h> int main(){ int aa; unsigned int bb = ...
- Bullet:ORACLE Using SQL Plan Management(一)
SQL Plan Management如何工作? 当一个SQL硬解析时,基于成本的优化器CBO会生成多个执行计划,并从这些执行计划中选择一个优化器认为最低成本的执行计划. 如果SQL plan bas ...
- NOIP 2008 传纸条(洛谷P1006,动态规划递推,滚动数组)
题目链接:P1006 传纸条 PS:伤心,又想不出来,看了大神的题解 AC代码: #include<bits/stdc++.h> #define ll long long using na ...
- 十二届 - CSU 1803 :2016(同余定理)
题目地址:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1803 Knowledge Point: 同余定理:两个整数a.b,若它们除以整数m所 ...
- IN语句改写EXISTS
-- IN SELECT T1.* FROM role_menu T1 WHERE T1.ROLEUUID IN ( SELECT T2.uuid FROM role T2 WHERE T2.UUID ...
- mysql连接错误解决(ERROR 2049 (HY000): Connection using old (pre-4.1.1) authentication protocol ref used (client option 'secure_auth' enabled))
当使用mysql的新版本是,连接老版本的mysql,就会有可能报: ERROR 2049 (HY000): Connection using old (pre-4.1.1) authenticatio ...
- mesh topology for airfoil, wing, blade, turbo
ref Ch. 5, Anderson, CFD the basics with applications numerical grid generation foundations and appl ...
- 分布式数据库中CAP原理(CAP+BASE)
分布式数据库中CAP原理(CAP+BASE) 传统的ACID 1)原子性(Atomicity): 事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务里的所有操作都成功. 2)一致性(Con ...
- WebSocket客户端学习
1. WebSocket是一种网络通讯协议 参考文档:http://www.ruanyifeng.com/blog/2017/05/websocket.html https://github.com/ ...
- EF中避免查询重复执行的手段
由于ef有lazyload机制,编写的查询语句往往都没有立即执行,当你轮训结果集的时候才会将查询翻译成database端的sql语句,执行sql将结果返回到方法中.但是,下次再使用前面的结果集的时候, ...