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 旅 ...
随机推荐
- js001-JavaScript简介
js001-JavaScript简介 1. JavaScript实现 JavaScript 的三个重要组成部分如下图 1.1.ECMAScript 1.1.1 版本 ...
- PHP责任链设计模式
<?php //责任链设计模式 /** * 每个对象,储存着对自己上级的引用, * 如果自己处理不了,交给上一级. */ class board{ protected $power=1; pro ...
- vbox 网络配置文件
sz /etc/sysconfig/network-scripts/ifcfg-eth1 #VAGRANT-BEGIN # The contents below are automatically g ...
- telnet连接ip
win7 telnet命令无法开启的解决方案(不是内部命令或外部命令) 出处:西西整理 作者:西西 日期:2012-12-21 14:22:06 [大 中 小] 评论: 0 | 我要发表看法 如果你想 ...
- scrapy1_官网教程
https://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/tutorial.html 本篇文章主要介绍如何使用编程的方式运行Scrapy爬虫. 在开始本文之 ...
- UDP SOCKET网络通信 C#
接收端 using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Thread ...
- Eclipse 安装svn插件及使用
1 安装 参考:http://welcome66.iteye.com/blog/1845176 通过svn插件安装,地址: Links for 1.8.x Release: Eclipse updat ...
- 为什么可以用while(cin)?
为什么可以用while(cin)? /** * @brief The quick-and-easy status check. * * This allows you to write const ...
- Sort 整理
文章.图片参考:http://www.jianshu.com/p/1b4068ccd505?hmsr=toutiao.io&utm_medium=toutiao.io&utm_sour ...
- CodeForces 710A King Moves(水题-越界问题)
题目链接:http://codeforces.com/problemset/problem/710/A 题目大意:在一个棋盘中给出一个位置,判断该位置周围8个点还有几个点可以摆放棋子. AC代码解释解 ...