[loj#2005][SDOI2017]相关分析 _线段树
「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]相关分析 _线段树的更多相关文章
- 【BZOJ4821】[SDOI2017]相关分析(线段树)
[BZOJ4821][SDOI2017]相关分析(线段树) 题面 BZOJ 洛谷 题解 看看询问要求的东西是什么.把所有的括号拆开,不难发现要求的就是\(\sum x,\sum y,\sum xy,\ ...
- bzoj4821 && luogu3707 SDOI2017相关分析(线段树,数学)
题目大意 给定n个元素的数列,每一个元素有x和y两种元素,现在有三种操作: \(1\ L\ R\) 设\(xx\)为\([l,r]\)的元素的\(x_i\)的平均值,\(yy\)同理 求 \(\fra ...
- 洛谷3707 [SDOI2017] 相关分析 【线段树】
分析: 化简一下就行了,注意一下平方和公式的运用以及精度的误差. 代码: #include<bits/stdc++.h> using namespace std; ; int n,m; i ...
- BZOJ4821 SDOI2017相关分析(线段树)
纯粹的码农题.维护x的和.y的和.xy的和.x2的和即可.可能会炸long long. #include<iostream> #include<cstdio> #include ...
- BZOJ_4636_蒟蒻的数列_线段树+动态开点
BZOJ_4636_蒟蒻的数列_线段树+动态开点 Description 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个数列,初始值均为0,他进行N次操作,每次将 ...
- BZOJ_3252_攻略_线段树+dfs序
BZOJ_3252_攻略_线段树+dfs序 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏< ...
- BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针
BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针 Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间, ...
- BZOJ_2124_等差子序列_线段树+Hash
BZOJ_2124_等差子序列_线段树+Hash Description 给一个1到N的排列{Ai},询问是否存在1<=p1<p2<p3<p4<p5<…<pL ...
- BZOJ_1826_[JSOI2010]缓存交换 _线段树+贪心
BZOJ_1826_[JSOI2010]缓存交换 _线段树+贪心 Description 在计算机中,CPU只能和高速缓存Cache直接交换数据.当所需的内存单元不在Cache中时,则需要从主存里把数 ...
随机推荐
- LA 6972 Domination
6972 Domination Edward is the headmaster of Marjar University. He is enthusiastic about chess and of ...
- assert 笔记
目录 什么是assert? assert使用 assert错误使用 什么是assert? Python 的 assert 语句是一个 debug 的好工具,主要用于测试一个条件是否满足.如果测试的条件 ...
- Codeforces 940 E.Cashback (单调队列,dp)
Codeforces 940 E.Cashback 题意:一组数,要分为若干个区间,每个区间长度为ki(1<=ki<=n),并且对于每个区间删去前ki/c(向下取整)个小的数(即对区间升序 ...
- 使用UltraISO制作linux系统安装u盘启动盘
1.首先打开UltraISO软件,尽量下载最新版的,小编曾用某个旧版的UltraISO,制作的安装盘,不能不能识别磁盘,安装失败! 2.点击工具栏中的第二个打开镜像文件工具,如图红色方框标志按钮,然后 ...
- 前端知识点回顾——Javascript篇(四)
Symbol 为什么需要symbol ES5里面对象的属性名都是字符串,如果你需要使用一个别人提供的对象,你对这个对象有哪些属性也不是很清楚,但又想为这个对象新增一些属性,那么你新增的属性名就很可能和 ...
- C memcpy()用法
https://blog.csdn.net/qq_21792169/article/details/50561570
- 2.3 Go语言基础之数组
本文主要介绍Go语言中数组(array)及它的基本使用. 一.Array(数组) 数组是同一种数据类型元素的集合. 在Go语言中,数组从声明时就确定,使用时可以修改数组成员,但是数组大小不可变化. 基 ...
- Android关闭通知栏后toast无法提示的解决方案
https://github.com/getActivity/ToastUtils PS:release版本注意加上混淆规则
- JS选择器querySelector和~All,三个原生选择器
定义: querySelector() 方法返回文档中匹配指定 CSS 选择器的一个元素. 注意: querySelector() 方法仅仅返回匹配指定选择器的第一个元素.如果你需要返回所有的元素,请 ...
- Java SpringBoot React Redux
1.字符串转换相关 - React 前端JS部分 JSON.parse(JSON.stringify(copyRow)); 2.字符串分隔相关,弹出confirm确认框,显示换行信息 - React ...