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 旅 ...
随机推荐
- uC/OS-II实现TEST.MAK块
################################################################################ ...
- wpf listbox 内的内容显示问题,需要设置里面的itemsPresenter
有时候控件并非维护本身逻辑,而是依赖于父子元素的,如了上诉的ContentPresenter,我们还有一个非常常用的ListBox控件,因为继承自ItemsControl,所以有一个ItemsPane ...
- accept()
在一个套接口接受一个连接.accept()是c语言中网络编程的重要的函数,windows系统在#include<winsock.h> ,而linux系统在#include <sys/ ...
- Java适配器设计模式
适配器设计模式,一个接口首先被一个抽象类先实现(此抽象类通常称为适配器类),并在此抽象类中实现若干方法(但是这个抽象类中的方法体是空的),则以后的子类直接继承此抽象类,就可以有选择地覆写所需要的方法. ...
- 在 docker中 运行 mono /jexus server 并部署asp.net mvc站点
http://linuxdot.net/bbsfile-3988 1. 安装 docker: // docker 1.7 新版 安装非常容易,理论上说,在主流的任意linux发行版上都可以 ...
- Tomcat服务器原理详解
[目录]本文主要讲解Tomcat启动和部署webapp时的原理和过程,以及其使用的配置文件的详解.主要有三大部分: 第一部分.Tomcat的简介和启动过程 第二部分.Tomcat部署webapp 第三 ...
- Effective Objective-C 2.0 — 第12条:理解消息转发机制
11 条讲解了对象的消息传递机制 12条讲解对象在收到无法解读的消息之后会发生什么,就会启动“消息转发”(message forwarding)机制, 若对象无法响应某个选择子,则进入消息转发流程. ...
- Yii2 yii2-imagine的使用
<?php /** * 图片常用处理 * * 需要 yii/yii2-imagine 的支持 * php composer.phar require --prefer-dist yiisoft/ ...
- jquery插件写法
//传统写法 //全局方法 ;(function($){ $.method = function(){ } //or $.obj = { method1:function(){}, method2:f ...
- QT实现贪吃蛇
board.h #ifndef BOARD_H #define BOARD_H #define MAX_X 40 #define MAX_Y 30 #define NORMAL_LABEL 0//普通 ...