NOIP“对偶”题:还教室
先说一下思路:
方差可以经过恒等变形变成
x12 + x22 + ... + xn2 + 2a(x1 + x2 + ... + xn) + na2
所以维护平方和、连续和即可
平均数我就不再推了……
天哪我连线段树都能写错!
写篇随笔记录一下我的易错点,顺便与大家交流一下……
void maintain(int L, int R, int o) {
int M = L + R >> , lc = o << , rc = lc | , ln = M - L + , rn = R - M;
sqrv[o] = sqrv[lc] + (addv[lc] * sumv[lc] << ) + ln * addv[lc] * addv[lc] + sqrv[rc] + (addv[rc] * sumv[rc] << ) + rn * addv[rc] * addv[rc];
sumv[o] = sumv[lc] + addv[lc] * ln + sumv[rc] + addv[rc] * rn;
return ;
}
在maintain函数中,须注意
sumv[o] = sumv[lc] + addv[lc] * ln + sumv[rc] + addv[rc] * rn;
不能偷懒,写成下面这样是错误的(想一想,为什么)
sumv[o] = sumv[lc] + sumv[rc] + addv[o] * (R - L + );
我解释一下:这样会将每段区间自己的addv[o]加上,那么query函数if(ql <= L && R <= qr)之中就不能加上add += addv[o]这句话了
void query(int L, int R, int o, LL add) {
if(ql <= L && R <= qr) {
add += addv[o]; int n = R - L + ;
_sum += sumv[o] + add * n;
_sqr += sqrv[o] + (add * sumv[o] << ) + n * add * add;
} else {
int M = L + R >> , lc = o << , rc = lc | ;
if(ql <= M) query(L, M, lc, add + addv[o]);
if(qr > M) query(M+, R, rc, add + addv[o]);
}
return ;
}
(这是个人写线段树的习惯,习惯不一样的话易错点不再适用)
完整代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#include <vector>
#include <queue>
#include <cstdlib>
using namespace std; int read() {
int x = , f = ; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -; c = getchar(); }
while(isdigit(c)){ x = x * + c - ''; c = getchar(); }
return x * f;
} #define LL long long
#define maxn 100010
struct Fraction {
LL a, b; LL gcd(LL a, LL b) {
return !b ? a : gcd(b, a % b);
} Fraction maintain() {
if(!a) { b = ; return *this; }
LL t = gcd(a, b); a /= t; b /= t;
return *this;
} Fraction operator - (const Fraction& t) const {
Fraction ans = (Fraction){ a * t.b - t.a * b, b * t.b };
return ans.maintain();
}
Fraction operator -= (const Fraction& t) {
*this = *this - t;
return *this;
} void print() {
printf("%lld/%lld\n", a, b);
return ;
}
} ;
LL sumv[maxn*], sqrv[maxn*], addv[maxn*], A[maxn]; void maintain(int L, int R, int o) {
int M = L + R >> , lc = o << , rc = lc | , ln = M - L + , rn = R - M;
sqrv[o] = sqrv[lc] + (addv[lc] * sumv[lc] << ) + ln * addv[lc] * addv[lc] + sqrv[rc] + (addv[rc] * sumv[rc] << ) + rn * addv[rc] * addv[rc];
sumv[o] = sumv[lc] + addv[lc] * ln + sumv[rc] + addv[rc] * rn;
return ;
} void build(int L, int R, int o) {
if(L == R){ sumv[o] = A[L]; sqrv[o] = A[L] * A[R]; }
else {
int M = L + R >> , lc = o << , rc = lc | ;
build(L, M, lc);
build(M+, R, rc);
maintain(L, R, o);
}
return ;
} int ql, qr; LL v;
void update(int L, int R, int o) {
if(ql <= L && R <= qr) addv[o] += v;
else {
int M = L + R >> , lc = o << , rc = lc | ;
addv[lc] += addv[o]; addv[rc] += addv[o]; addv[o] = ;
if(ql <= M) update(L, M, lc);
if(qr > M) update(M+, R, rc);
maintain(L, R, o);
}
return ;
} LL _sum, _sqr;
void query(int L, int R, int o, LL add) {
if(ql <= L && R <= qr) {
add += addv[o]; int n = R - L + ;
_sum += sumv[o] + add * n;
_sqr += sqrv[o] + (add * sumv[o] << ) + n * add * add;
} else {
int M = L + R >> , lc = o << , rc = lc | ;
if(ql <= M) query(L, M, lc, add + addv[o]);
if(qr > M) query(M+, R, rc, add + addv[o]);
}
return ;
} int main() {
int n = read(), m = read();
for(int i = ; i <= n; i++) A[i] = read();
build(, n, );
while(m--) {
int tp = read(); ql = read(); qr = read();
if(tp == ) {
v = read(); update(, n, );
} else {
_sum = _sqr = ;
query(, n, , );
Fraction ans; LL tn = qr - ql + ;
if(tp == ) { // average
ans = (Fraction){ _sum, tn };
ans.maintain();
} else { // variance
ans = (Fraction){ _sqr * tn - _sum * _sum, tn * tn };
ans.maintain();
}
ans.print();
}
} return ;
}
NOIP“对偶”题:还教室的更多相关文章
- noip做题记录+挑战一句话题解?
因为灵巧实在太弱辽不得不做点noip续下命QQAQQQ 2018 积木大赛/铺设道路 傻逼原题? 然后傻逼的我居然检查了半天是不是有陷阱最后花了差不多一个小时才做掉我做过的原题...真的傻逼了我:( ...
- Noip前的大抱佛脚----Noip真题复习
Noip前的大抱佛脚----Noip真题复习 Tags: Noip前的大抱佛脚 Noip2010 题目不难,但是三个半小时的话要写四道题还是需要码力,不过按照现在的实力应该不出意外可以AK的. 机器翻 ...
- $NOIp$做题记录
虽然去年做了挺多了也写了篇一句话题解了但一年过去也忘得差不多了$kk$ 所以重新来整理下$kk$ $2018(4/6$ [X]积木大赛 大概讲下$O(n)$的数学方法. 我是从分治类比来的$QwQ$. ...
- CH Round #52 还教室[线段树 方差]
还教室 CH Round #52 - Thinking Bear #1 (NOIP模拟赛) [引子]还记得 NOIP 2012 提高组 Day2 中的借教室吗?时光飞逝,光阴荏苒,两年过去了,曾经借教 ...
- NOIP 2012 Day2T2 借教室题解
NOIP 2012 Day2T2 借教室题解 题目传送门:http://codevs.cn/problem/1217/ 题目描述 Description 在大学期间,经常需要租借教室.大到院系举办活动 ...
- NOIP模拟题汇总(加厚版)
\(NOIP\)模拟题汇总(加厚版) T1 string 描述 有一个仅由 '0' 和 '1' 组成的字符串 \(A\),可以对其执行下列两个操作: 删除 \(A\)中的第一个字符: 若 \(A\)中 ...
- 历年NOIP真题总结
前言:最近把历年的NOIP真题肝了一遍(还有3个紫题先咕掉了),主要是到1998年的提高组的题.把题目的做题简要思路搁在这儿,一个是为了考前翻一翻,想想自己的哪些思路要梳理的什么什么的,反正怎么说呢, ...
- NOIP原题 斗地主(20190804)
题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关 系根据牌的数码表示如下:3<4&l ...
- NOIP真题索引
NOIP真题索引 NOIP2019 Day 1 格雷码 括号树 树上的数 Day 2 Emiya 家今天的饭 划分 树的重心 NOIP2018 Day 1 铺设道路 货币系统 赛道修建 Day 2 旅 ...
随机推荐
- Linux 中,如何显示 (gcc)make时实际执行命令
问题: 调试编译问题,如何获取,GCC(或许make)时,实际编译器和链接器正在执行的命令? 解决方法: 方法一:通用方法 使用dry run,如下 $ make -n 这将显示make 命令正在试图 ...
- C#------各种常见错误解决方法
1.错误:模型生成过程中检测到一个或多个验证错误 表示实体中的数据列没有和SQLServer数据库里面的表中的数据列完全相同,比如SQLServer中有ID,Name,Post,那么实体中也应该有ID ...
- Javascript中call、apply、bind函数
javascript在函数创建的时候除了自己定义的参数外还会自动新增this和arguments两个参数 javascript中函数也是对象,call.apply.bind函数就是函数中的三个函数,这 ...
- Kindeditor 编辑器POST提交的时候会出现符号被转换
Kindeditor编辑器输入符号单引号,双引号,斜杠 都会被转义 解决办法 $date['content']=$this->textString($_POST['content']); pub ...
- php生成excle
方法一: 新建index.php,代码如下 <?php header("Content-type:application/vnd.ms-excel"); header(&qu ...
- JavaWeb学习总结(三)——Tomcat服务器学习和使用(二) 包含https 非对称秘钥 NB
JavaWeb学习总结(三)--Tomcat服务器学习和使用(二) 一.打包JavaWeb应用 在Java中,使用"jar"命令来对将JavaWeb应用打包成一个War包,jar命 ...
- 使用Java练习算法常用的基本操作
一.使用Java练习算法常常需要使用控制台的数据输入和输出,下面记录一下基本的使用方法: 基本用法 import java.util.*; public class Main { public sta ...
- C# 表达式树demo
class Program { static void Main(string[] args) { //创建Expression参数 var left = System.Linq.Expression ...
- MySql避免重复插入记录
今天用python抓取数据入库需要避免重复数据插入,在网上找了一些方法: 方案一:使用ignore关键字 如果是用主键primary或者唯一索引unique区分了记录的唯一性,避免重复插入记录可以使用 ...
- 来自 Google 的 R 语言编码风格指南
来自 Google 的 R 语言编码风格指南R 语言是一门主要用于统计计算和绘图的高级编程语言. 这份 R 语言编码风格指南旨在让我们的 R 代码更容易阅读.分享和检查. 以下规则系与 Google ...