【洛谷】【前缀和+st表】P2629 好消息,坏消息
【题目描述:】
uim在公司里面当秘书,现在有n条消息要告知老板。每条消息有一个好坏度,这会影响老板的心情。告知完一条消息后,老板的心情等于之前老板的心情加上这条消息的好坏度。最开始老板的心情是0,一旦老板心情到了0以下就会勃然大怒,炒了uim的鱿鱼。
uim为了不被炒,知道了了这些消息(已经按时间的发生顺序进行了排列)的好坏度,希望研究如何不让老板发怒。
uim必须按照时间的发生顺序逐条将消息告知给老板。不过uim可以使用一种叫“倒叙”的手法,例如有n条消息,小a可以从k,k+1,k+2...n,1,2...k-1这种顺序通报。
他希望知道,有多少个k,从k开始通报到n然后从1通报到k-1可以让老板不发怒。
【输入格式:】
第一行一个整数n(1 <= n <= 10^6),表示有n个消息。
第二行n个整数,按时间顺序给出第i条消息的好坏度Ai(-1000 <= Ai <= 1000)
【输出格式:】
一行一个整数,表示可行的方案个数。
在旁边wzx大(巨)佬的指点下切掉了这道题
[算法分析:]
对于要判断区间\([l,\ r]\)内在某一时刻的和是否为负值,只需要看从\([l,\ r]\)的前缀和序列的值是否为负.
(这道题是要求对于一个点\(i\),判断\([i,\ n]\)和\([1,\ i-1]\)中某一时刻的前缀和是否存在负值)
那怎样快速地求出这个前缀和序列并判断是否有负值呢?
枚举的方法显然并不高效,反而和直接模拟的复杂度一样了,抛掉
判断是否有负值,可以找到一个标准,只要这个标准非负,那整个序列也就没有负值了
显然的,标准应选为\([l,\ r]\)的前缀和序列的最小值,便可以使用st表或者线段树来快速查询.
那又应该如何求出\([l,\ r]\)的前缀和序列呢?每次求一遍?显然复杂度会降到约为\(O(n^3)\)
对于一个序列\(a\),\([1,\ r]\)的前缀和序列的最小值再减去\([1,\ l - 1]\)的元素和,即为\([l,\ r]\)的前缀和序列最小值
即:$$min{\sum_{j = l}^{r}\sum_{i = l}^{j} a_i} = min{\sum_{j = 1}^{r}\sum_{i = 1}^{j} a_i} - \sum_{i = 1}^{l - 1}a_i$$
所以当我们根据序列\(a\)求出\([l,\ r]\)的前缀和序列sum时,使用st表维护这个序列sum的最小值,
就可以做到\(O(1)\)查询\(min\{\sum_{j = l}^{r}\sum_{i = l}^{j} a_i\}\)
预处理复杂度\(O(nlog_2n)\),算法主体的时间复杂度为\(O(n)\)
而使用线段树也可以维护最小值,根据前缀和序列建树,预处理\(O(n)\),算法主体复杂度为\(O(nlog_2n)\),和st表差不多。
(但是实测好像st表跑的慢一些)
也可以使用单调队列来求最值,复杂度应该是\(O(n)\),比st表和线段树都要快,但是我不会QwQ
\([Code:]\)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int MAXN = 1e6 + 1;
const int K = 20 + 1;
int n;
int a[MAXN], sum[MAXN];
int st[MAXN][K], Log2[MAXN];
inline int read() {
int x=0, f=1; char ch=getchar();
while(ch<'0' || ch>'9') {
if(ch == '-') f = -1;
ch = getchar();
}
while(ch>='0' && ch<='9')
x=(x<<3)+(x<<1)+ch-48, ch=getchar();
return x * f;
}
inline int Query(int l, int r) {
int x = Log2[r - l + 1];
return min(st[l][x], st[r-(1<<x)+1][x]);
}
int main() {
n = read();
for(int i=1; i<=n; ++i) a[i] = read();
for(int i=1; i<=n; ++i)
st[i][0] = sum[i] = sum[i-1] + a[i];
for(int j=1; j<=K; ++j)
for(int i=1; i+(1<<j)-1<=n; ++i)
st[i][j] = min(st[i][j-1], st[i+(1<<(j-1))][j-1]);
for(int i=0; (1<<i)<=n; ++i) Log2[1<<i] = i;
for(int i=1; i<=n; ++i)
if(!Log2[i]) Log2[i] = Log2[i-1];
int ans = 0;
for(int i=1; i<=n; ++i) {
if(Query(i, n)-sum[i-1] < 0) continue;
if(Query(1, i-1) + sum[n] - sum[i-1] >= 0) ++ans;
}
printf("%d\n", ans);
}
【洛谷】【前缀和+st表】P2629 好消息,坏消息的更多相关文章
- 【洛谷】【st表+模拟】P1311 选择客栈
[题目描述:] 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖 ...
- 线段树【p2629】 好消息,坏消息
顾z 你没有发现两个字里的blog都不一样嘛 qwq 题目描述-->p2629 好消息,坏消息 历程 刚开始看到这个题,发现是需要维护区间和,满心欢喜敲了一通线段树,简单debug之后交上去 \ ...
- 【题解】洛谷 P1014 【Cantor表】
1. 我们先引入三角形数的概念: >定数目的点或圆在等距离的排列下可以形成一个等边三角形,这样的数被称为三角形数. >古希腊著名科学家毕达哥拉斯把数1,3,6,10,15,21……这些数量 ...
- 洛谷 - P2181 - 对角线 - 打表 - 组合数学
https://www.luogu.org/problemnew/show/P2181 对于某条对角线,除去从两端出发的对角线,其他的都与它有1个交点. 每个点有(n-3)条对角线,每条对角线和其余C ...
- 洛谷 P1816 忠诚 ST函数
题目描述 老管家是一个聪明能干的人.他为财主工作了整整10年,财主为了让自已账目更加清楚.要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意.但是由于一些人的挑拨,财主还是对管家产生了 ...
- 【洛谷3865】 【模板】ST表(猫树)
传送门 洛谷 Solution 实测跑的比ST表快!!! 这个东西也是\(O(1)\)的,不会可以看我上一篇Blog 代码实现 代码戳这里
- 【洛谷】P2880 [USACO07JAN]平衡的阵容Balanced Lineup(st表)
题目背景 题目描述: 每天,农夫 John 的N(1 <= N <= 50,000)头牛总是按同一序列排队. 有一天, John 决定让一些牛们玩一场飞盘比赛. 他准备找一群在对列中为置连 ...
- 洛谷P4501/loj#2529 [ZJOI2018]胖(ST表+二分)
题面 传送门(loj) 传送门(洛谷) 题解 我们对于每一个与宫殿相连的点,分别计算它会作为多少个点的最短路的起点 若该点为\(u\),对于某个点\(p\)来说,如果\(d=|p-u|\),且在\([ ...
- 【洛谷P1816】忠诚——ST表做法
看了两个小时RMQ并位运算,对二进制勉勉强强有了个初步了解,不能说精通(可能今年CSP前都做不到精通),但是记熟板子做做题还是没有问题的 以下是正式题解,相信你看过了题目,我介绍的是ST表的做法(很简 ...
随机推荐
- JWT操作(.net)
1.JWT定义 JWT(Json Web Token)是一种用于双方之间传递安全信息的简洁的.URL安全的表述性声明规范.JWT作为一个开放的标准( RFC 7519 ),定义了一种简洁的,自包含的方 ...
- 在net中json序列化与反序列化
准备好饮料,我们一起来玩玩JSON,什么是Json:一种数据表示形式,JSON:JavaScript Object Notation对象表示法 Json语法规则: 数据在键值对中 数据由逗号分隔 花括 ...
- Java并发编程-闭锁
闭锁是一种同步器 ( Synchronizer ),它可以延迟线程的进度直到线程到达终止状态,CountDownLatch是一个灵活的闭锁实现:1)允许一个或多个线程等待一个事件集的发生,闭锁的状态包 ...
- Oracle TO_DATE() 函数格式化时间【全】
TO_DATE格式(以时间:2007-11-02 13:45:25为例) Year: yy two digits 两位年 显 ...
- Vue脚手架
https://cli.vuejs.org/zh/guide/ Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,提供: 通过 @vue/cli 搭建交互式的项目脚手架. 通过 @vu ...
- Python-模拟键盘输入的代码片段
特别说明:要先安装pywind32类库!!! import win32apiimport win32conimport win32guifrom ctypes import *import time ...
- python学习之老男孩python全栈第九期_day002知识点总结
1. 格式化输出: (1) %(占位符) s(str字符串) d(digit数字) (2) 想单纯输入%,需要输入两个%(%和占位符冲突),前面的%相当于转义. 2. while else循环: (1 ...
- 2.logback+slf4j+janino 配置项目的日志输出
作者QQ:1095737364 QQ群:123300273 欢迎加入! 1.创建项目 参考:http://www.cnblogs.com/yysbolg/p/6898453.html 2 ...
- js-设计模式学习笔记-策略模式
策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换(相互替换:表现为它们具有相同的目标和意图). 策略模式的目的是讲算法的使用与算法的实现分离开来. 一个基于策略模式的程 ...
- JavaScript 事件处理机制
DOM 事件流 DOM 是一个树型结构,当一个HTML元素产生一个事件时,该事件会在该元素结点与根节点之间按特定的顺序传播,路径所经过的节点都会收到该事件,这个传播过程可称为DOM事件流.而事件传播的 ...