「SDOI2017」相关分析

题目链接https://loj.ac/problem/2005


题解

把上面的式子拆掉,把下面的式子拆掉。

发现所有的东西都能用线段树暴力维护。

代码

#include <bits/stdc++.h>

#define N 100010 

#define ls p << 1

#define rs p << 1 | 1

using namespace std;

typedef double db;

typedef double ll;

ll sum[N << 2], tagx1[N << 2], tagx2[N << 2], tagy1[N << 2], tagy2[N << 2], sum2[N << 2];

bool tag1[N << 2], tag2[N << 2];

ll sumx[N << 2], sumy[N << 2];

char *p1, *p2, buf[100000];

#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )

int rd() {
int x = 0, f = 1;
char c = nc();
while (c < 48) {
if (c == '-')
f = -1;
c = nc();
}
while (c > 47) {
x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
}
return x * f;
} inline void pushup(int p) {
sum[p] = sum[ls] + sum[rs];
sumx[p] = sumx[ls] + sumx[rs];
sumy[p] = sumy[ls] + sumy[rs];
sum2[p] = sum2[ls] + sum2[rs];
} void pls1(int l, int r, int s, int t, int p) {
int L = r - l + 1;
sum[p] += (ll)t * sumx[p] + (ll)s * sumy[p] + (ll)s * t * L;
sum2[p] += sumx[p] * s * 2 + (ll)s * s * L;
sumx[p] += (ll)s * L;
sumy[p] += (ll)t * L;
if (tag2[p]) {
tagx2[p] += s;
tagy2[p] += t;
}
else {
tagx1[p] += s;
tagy1[p] += t;
tag1[p] = true;
}
} inline ll bfr2(int x) {
return (ll)x * (x + 1) * (2 * x + 1) / 6;
} inline ll bfr1(int x) {
return (ll)x * (x + 1) / 2;
} void pls2(int l, int r, int s, int t, int p) {
int L = r - l + 1;
sum[p] = bfr2(r) - bfr2(l - 1) + (ll)(s + t) * (bfr1(r) - bfr1(l - 1)) + (ll)L * s * t;
sum2[p] = bfr2(r) - bfr2(l - 1) + (ll)2 * s * (bfr1(r) - bfr1(l - 1)) + (ll)L * s * s;
sumx[p] = bfr1(r) - bfr1(l - 1) + (ll)L * s;
sumy[p] = bfr1(r) - bfr1(l - 1) + (ll)L * t;
tag1[p] = false;
tagx1[p] = tagy1[p] = 0;
tag2[p] = true;
tagx2[p] = s;
tagy2[p] = t;
} inline void pushdown(int l, int r, int p) {
if (tag1[p]) {
int mid = (l + r) >> 1;
pls1(l, mid, tagx1[p], tagy1[p], ls);
pls1(mid + 1, r, tagx1[p], tagy1[p], rs);
tagx1[p] = tagy1[p] = 0;
tag1[p] = false;
}
if (tag2[p]) {
int mid = (l + r) >> 1;
pls2(l, mid, tagx2[p], tagy2[p], ls);
pls2(mid + 1, r, tagx2[p], tagy2[p], rs);
tagx2[p] = tagy2[p] = 0;
tag2[p] = false;
}
} void update1(int x, int y, int s, int t, int l, int r, int p) {
if (x <= l && r <= y) {
pls1(l, r, s, t, p);
return;
}
int mid = (l + r) >> 1;
pushdown(l, r, p);
if (x <= mid) {
update1(x, y, s, t, l, mid, ls);
}
if (mid < y) {
update1(x, y, s, t, mid + 1, r, rs);
}
pushup(p);
} void update2(int x, int y, int s, int t, int l, int r, int p) {
if (x <= l && r <= y) {
pls2(l, r, s, t, p);
return;
}
int mid = (l + r) >> 1;
pushdown(l, r, p);
if (x <= mid) {
update2(x, y, s, t, l, mid, ls);
}
if (mid < y) {
update2(x, y, s, t, mid + 1, r, rs);
}
pushup(p);
} ll queryx1(int x, int y, int l, int r, int p) {
if (x <= l && r <= y) {
return sumx[p];
}
int mid = (l + r) >> 1;
ll ans = 0;
pushdown(l, r, p);
if (x <= mid) {
ans += queryx1(x, y, l, mid, ls);
}
if (mid < y) {
ans += queryx1(x, y, mid + 1, r, rs);
}
return ans;
} ll queryy1(int x, int y, int l, int r, int p) {
if (x <= l && r <= y) {
return sumy[p];
}
int mid = (l + r) >> 1;
ll ans = 0;
pushdown(l, r, p);
if (x <= mid) {
ans += queryy1(x, y, l, mid, ls);
}
if (mid < y) {
ans += queryy1(x, y, mid + 1, r, rs);
}
return ans;
} ll query(int x, int y, int l, int r, int p) {
if (x <= l && r <= y) {
return sum[p];
}
int mid = (l + r) >> 1;
ll ans = 0;
pushdown(l, r, p);
if (x <= mid) {
ans += query(x, y, l, mid, ls);
}
if (mid < y) {
ans += query(x, y, mid + 1, r, rs);
}
return ans;
} ll query2(int x, int y, int l, int r, int p) {
if (x <= l && r <= y) {
return sum2[p];
}
int mid = (l + r) >> 1;
ll ans = 0;
pushdown(l, r, p);
if (x <= mid) {
ans += query2(x, y, l, mid, ls);
}
if (mid < y) {
ans += query2(x, y, mid + 1, r, rs);
}
return ans;
} ll a1[N], a2[N]; void build(int l, int r, int p) {
if (l == r) {
sum[p] = a1[l] * a2[l];
sum2[p] = a1[l] * a1[l];
sumx[p] = a1[l];
sumy[p] = a2[l];
return;
}
int mid = (l + r) >> 1;
build(l, mid, ls);
build(mid + 1, r, rs);
pushup(p);
} int main() {
// freopen("gold.in", "r", stdin);
// freopen("gold.out", "w", stdout);
int n = rd(), Q = rd();
for (int i = 1; i <= n; i ++ ) {
a1[i] = rd();
}
for (int i = 1; i <= n; i ++ ) {
a2[i] = rd();
}
build(1, n, 1);
while (Q -- ) {
int opt = rd();
if (opt == 1) {
int l = rd(), r = rd();
db Up;
int L = r - l + 1;
Up = query(l, r, 1, n, 1);
Up -= (db)queryx1(l, r, 1, n, 1) * queryy1(l, r, 1, n, 1) / L;
db Down;
Down = query2(l, r, 1, n, 1);
Down -= (db)queryx1(l, r, 1, n, 1) * queryx1(l, r, 1, n, 1) / L;
printf("%.10lf\n", Up / Down);
}
else if (opt == 2) {
int l = rd(), r = rd(), s = rd(), t = rd();
update1(l, r, s, t, 1, n, 1);
}
else {
int l = rd(), r = rd(), s = rd(), t = rd();
update2(l, r, s, t, 1, n, 1);
}
}
return 0;
}

小结:对拍的时候要记得,数据尽量和题面吻合,不然容易出一些奇奇怪怪的错误。比如说这个题考试的时候,我就有个值忘记开$long\ long$,对拍没拍出来因为我保证数据非常小。

[loj#2005][SDOI2017]相关分析 _线段树的更多相关文章

  1. 【BZOJ4821】[SDOI2017]相关分析(线段树)

    [BZOJ4821][SDOI2017]相关分析(线段树) 题面 BZOJ 洛谷 题解 看看询问要求的东西是什么.把所有的括号拆开,不难发现要求的就是\(\sum x,\sum y,\sum xy,\ ...

  2. bzoj4821 && luogu3707 SDOI2017相关分析(线段树,数学)

    题目大意 给定n个元素的数列,每一个元素有x和y两种元素,现在有三种操作: \(1\ L\ R\) 设\(xx\)为\([l,r]\)的元素的\(x_i\)的平均值,\(yy\)同理 求 \(\fra ...

  3. 洛谷3707 [SDOI2017] 相关分析 【线段树】

    分析: 化简一下就行了,注意一下平方和公式的运用以及精度的误差. 代码: #include<bits/stdc++.h> using namespace std; ; int n,m; i ...

  4. BZOJ4821 SDOI2017相关分析(线段树)

    纯粹的码农题.维护x的和.y的和.xy的和.x2的和即可.可能会炸long long. #include<iostream> #include<cstdio> #include ...

  5. BZOJ_4636_蒟蒻的数列_线段树+动态开点

    BZOJ_4636_蒟蒻的数列_线段树+动态开点 Description 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个数列,初始值均为0,他进行N次操作,每次将 ...

  6. BZOJ_3252_攻略_线段树+dfs序

    BZOJ_3252_攻略_线段树+dfs序 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏< ...

  7. BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针

    BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针 Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间, ...

  8. BZOJ_2124_等差子序列_线段树+Hash

    BZOJ_2124_等差子序列_线段树+Hash Description 给一个1到N的排列{Ai},询问是否存在1<=p1<p2<p3<p4<p5<…<pL ...

  9. BZOJ_1826_[JSOI2010]缓存交换 _线段树+贪心

    BZOJ_1826_[JSOI2010]缓存交换 _线段树+贪心 Description 在计算机中,CPU只能和高速缓存Cache直接交换数据.当所需的内存单元不在Cache中时,则需要从主存里把数 ...

随机推荐

  1. 数据库中的using语句,以及与try……catch……finally的关系

    每new一个对象,就会开辟一块资源.using(我们new的对象){……},“}”处自动释放占用的资源(即调用Dispose方法).等效于fianlly中调用Dispose方法. Dispose内部会 ...

  2. HDU - 5528Count a * b 数学公式推导

    HDU - 5528Count a * b 照着这个写的,忘了哪个大佬博客里的了, 但很多初学者,像我一样可能不懂其中一些符号的意义,还有为什么可以这样推导,所以我自己又推导了一下,并用自己的观点解释 ...

  3. 2018CCPC桂林站JStone Game

    题目描述 Alice and Bob are always playing game! The game today is about taking out stone from the stone ...

  4. node 中的global对象和process对象

    官方文档:http://nodejs.cn/api/ 因为Node.js是运行在服务区端的JavaScript环境,服务器程序和浏览器程序相比,最大的特点是没有浏览器的安全限制了,而且,服务器程序必须 ...

  5. 利用Python构建时间序列模型解决实际问题的正确姿势

    要本着应用到实际工作中目的去学时间序列分析,才能深入浅出的学会,不要纠结于理论,只听我的,我有信心说明白. 本章内容 趋势分析 序列分解 序列预测 序列分解 统计学基础铺垫 划分 时间序列按照季节性划 ...

  6. [Shell]常用语法

    赋值 FILE=$1 //=两边不能有空格 echo $FILE 逻辑判断 表达式 .if [ expression ]; then ... fi //[]两边必须有空格 . if [[ expres ...

  7. 在docker 安装gitlab

    一.Centos 7 上安装 官方文档:https://docs.docker.com/install/linux/docker-ce/centos/ 1.安装环境      yum install  ...

  8. ycache中redis主备功能设计及使用说明

    方案概述: 对于ycache-client,如下图,在一致性hash环上的每个节点都有一个备用的节点.正常情况下slave节点不参与key的分配(冷备).只有当master挂了,ycache clie ...

  9. Oracle存储过程、游标、函数

    SQL99是什么 (1)是操作所有关系型数据库的规则 (2)是第四代语言 (3)是一种结构化查询语言 (4)只需发出合法合理的命令,就有对应的结果显示 SQL的特点 (1)交互性强,非过程化 (2)数 ...

  10. mock的使用

    mock的重要性 mock就是对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建的方法.项目开发和测试过程中,遇到以下的情况时,就需要模拟结果返回. 1.当另一方接口或服务还未完成,阻碍项 ...