codeforces 895E
来源:互联网 发布:2016免费洗车软件 编辑:程序博客网 时间:2024/06/05 14:27
(线段树+2个lazy标记)
题意:先给定
思路:数组上的区间修改和查询,想到用线段树,这里线段树的每个结点维护三个值:数学期望总和,加法标记和乘法标记。为什么呢?假如题目给出一个操作1,那么对于
代码:
#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>#define lson p<<1,l,mid#define rson p<<1|1,mid+1,rusing namespace std;const int maxn = 100050;const double eps = 1e-6;double a[maxn], sum[maxn<<2];double addv[maxn<<2], multv[maxn<<2];int dcmp(double x) { if(fabs(x) < eps) return 0; return (x < 0 ? -1:1);}void push_up(int p) { sum[p] = sum[p<<1] + sum[p<<1|1];}/** lazy tags are designed for the lower nodes. **/void push_down(int p, int l, int r) { if(dcmp(multv[p])!=1 || dcmp(addv[p])!=0) { multv[p<<1] *= multv[p]; multv[p<<1|1] *= multv[p]; addv[p<<1] = multv[p]*addv[p<<1] + addv[p]; addv[p<<1|1] = multv[p]*addv[p<<1|1] + addv[p]; int mid = (l+r) >> 1; sum[p<<1] = multv[p]*sum[p<<1] + addv[p]*(mid-l+1); sum[p<<1|1] = multv[p]*sum[p<<1|1] + addv[p]*(r-mid); multv[p] = 1; addv[p] = 0; }}void build(int p, int l, int r) { multv[p] = 1; addv[p] = 0; if(l == r) { sum[p] = a[l]; return ; } int mid = (l+r) >> 1; build(lson); build(rson); push_up(p);}/** y = k*x + b; **/void modify(int p, int l, int r, int L, int R, double k, double b) { if(L <= l && r <= R) { sum[p] = k*sum[p] + b*(r-l+1); multv[p] *= k; addv[p] = k*addv[p] + b; return ; } push_down(p, l, r); int mid = (l+r) >> 1; if(L <= mid) modify(lson, L, R, k, b); if(R > mid) modify(rson, L, R, k, b); push_up(p);}double query(int p, int l, int r, int L, int R) { if(L <= l && r <= R) return sum[p]; push_down(p, l, r); double ret = 0; int mid = (l+r) >> 1; if(L <= mid) ret += query(lson, L, R); if(R > mid) ret += query(rson, L, R); return ret;}int main() { //freopen("test.txt","r",stdin); int n, q; scanf("%d%d",&n,&q); for(int i=1; i<=n; i++) scanf("%lf",&a[i]); build(1, 1, n); while(q --) { int op, l1, r1, l2, r2; scanf("%d",&op); if(op == 1) { scanf("%d%d%d%d",&l1,&r1,&l2,&r2); double size1 = r1 - l1 + 1, size2 = r2 - l2 + 1; double t1 = query(1, 1, n, l1, r1), t2 = query(1, 1, n, l2, r2); //printf("query t1: %f t2:%f\n",t1,t2); modify(1, 1, n, l1, r1, (size1-1)/size1, t2/(size2*size1)); modify(1, 1, n, l2, r2, (size2-1)/size2, t1/(size1*size2)); } else { scanf("%d%d",&l1,&l2); double ans = query(1, 1, n, l1, l2); printf("%f\n",ans); } } return 0;}
阅读全文
0 0
- codeforces 895E
- codeforces 163E e-Government
- 【Codeforces 163E】E-Government
- Codeforces 78E Evacuation
- 【dp】codeforces 83E
- Codeforces 124 E
- Codeforces 231E
- Codeforces 231E - Cactus
- Codeforces #163 Div2 E
- codeForces 35E
- Codeforces 35E
- Playlist codeforces 268E
- Codeforces 148E(Porcelain)
- codeforces round#177 E
- codeforces 203E Transportation
- CodeForces 254 E Dormitory
- codeforces日记371e
- Codeforces #81E Pairs
- jackSon注解-- @JsonInclude 注解不返回null值字段
- linux 安装mysql数据库——tar.gz包解压安装法 mysql数据库有多种安装方式,本文只介绍在Linux服务器上的tar.gz包解压安装法, 先通过mysql官网或者网络资源下载 my
- Mybatis分页插件-PageHelper的使用
- 题目:将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5(java)
- Javabean使用(一)
- codeforces 895E
- win10添加Windows照片查看器
- HashMap的底层实现
- Markdown example
- java-16(4)-工具类
- 学习uboot前奏之hardware-uart[s3c2440]
- windows系统如何通过命令实现挂载盘符
- Linux基本指令
- 内存分配函数