题目链接

BZOJ3521

题解

容易想到用前缀和搞

如果我们令\(p\)为\(1\),\(j\)为\(-1\),记前缀和为\(s[i]\)

我们就是要找到一段区间\([l,r]\),使得

\[\forall i \in [l,r] \quad s[i] - s[l - 1] \ge 0
\]

\[\forall i \in [l - 1,r - 1] \quad s[r] - s[i] \ge 0
\]

所以说\(s[l - 1]\)是区间\([l - 1,r]\)的最小值,\(s[r]\)是区间\([l - 1,r]\)的最大值

问题转化为了:我们需要找到最小值在左端,最大值在右端的最长区间

按照寻找最优区间的套路,我们枚举左端点,可以利用单调栈求出左端点满足要求的区间

然后在这个区间内查找最大值的位置【如果多个相同则取最右】,来更新答案

为什么一定是最大值的位置最优?因为最大值右边的一定不符,最大值左边的一定比当前答案小

复杂度\(O(nlogn)\),线段树没太多操作,甚至不用修改,所以常数很小,可以放心过

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
#define ls (u << 1)
#define rs (u << 1 | 1)
using namespace std;
const int maxn = 1000005,maxm = 100005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int mx[maxn << 2],A[maxn];
inline void upd(int u){
mx[u] = A[mx[ls]] > A[mx[rs]] ? mx[ls] : mx[rs];
}
void build(int u,int l,int r){
if (l == r) mx[u] = l;
else {
int mid = l + r >> 1;
build(ls,l,mid);
build(rs,mid + 1,r);
upd(u);
}
}
int query(int u,int l,int r,int L,int R){
if (l >= L && r <= R) return mx[u];
int mid = l + r >> 1;
if (mid >= R) return query(ls,l,mid,L,R);
else if (mid < L) return query(rs,mid + 1,r,L,R);
else {
int t1 = query(ls,l,mid,L,R),t2 = query(rs,mid + 1,r,L,R);
return A[t1] > A[t2] ? t1 : t2;
}
}
int n,st[maxn],top,r[maxn];
int main(){
n = read(); char c = getchar();
while (!isalpha(c)) c = getchar();
REP(i,n){
A[i] = A[i - 1] + (c == 'p' ? 1 : -1);
c = getchar();
}
build(1,1,n);
st[top = 1] = n;
int ans = 0,x;
for (int i = n - 1; ~i; i--){
while (top && A[i] <= A[st[top]]) top--;
if (!top) r[i] = n;
else r[i] = st[top] - 1;
st[++top] = i;
if (i + 1 <= r[i]){
x = query(1,1,n,i + 1,r[i]);
ans = max(ans,x - i);
}
}
printf("%d\n",ans);
return 0;
}

BZOJ3521 [Poi2014]Salad Bar 【线段树 + 单调栈】的更多相关文章

  1. Codeforces 781E Andryusha and Nervous Barriers 线段树 单调栈

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF781E.html 题目传送门 - CF781E 题意 有一个矩形,宽为 w ,高为 h .一开始会有 w 个 ...

  2. 洛谷P4425 转盘 [HNOI/AHOI2018] 线段树+单调栈

    正解:线段树+单调栈 解题报告: 传送门! 1551又是一道灵巧连题意都麻油看懂的题,,,,所以先解释一下题意好了,,,, 给定一个n元环 可以从0时刻开始从任一位置出发 每次可以选择向前走一步或者在 ...

  3. 线段树+单调栈+前缀和--2019icpc南昌网络赛I

    线段树+单调栈+前缀和--2019icpc南昌网络赛I Alice has a magic array. She suggests that the value of a interval is eq ...

  4. 牛客多校第四场sequence C (线段树+单调栈)

    牛客多校第四场sequence C (线段树+单调栈) 传送门:https://ac.nowcoder.com/acm/contest/884/C 题意: 求一个$\max {1 \leq l \le ...

  5. Codeforces 1175F - The Number of Subpermutations(线段树+单调栈+双针/分治+启发式优化)

    Codeforces 题面传送门 & 洛谷题面传送门 由于这场的 G 是道毒瘤题,蒟蒻切不动就只好来把这场的 F 水掉了 看到这样的设问没人想到这道题吗?那我就来发篇线段树+单调栈的做法. 首 ...

  6. [Codeforces1132G]Greedy Subsequences——线段树+单调栈

    题目链接: Codeforces1132G 题目大意:给定一个序列$a$,定义它的最长贪心严格上升子序列为$b$满足若$a_{i}$在$b$中则$a_{i}$之后第一个比它大的也在$b$中.给出一个数 ...

  7. BZOJ.4540.[HNOI2016]序列(莫队/前缀和/线段树 单调栈 RMQ)

    BZOJ 洛谷 ST表的一二维顺序一定要改过来. 改了就rank1了哈哈哈哈.自带小常数没办法. \(Description\) 给定长为\(n\)的序列\(A_i\).\(q\)次询问,每次给定\( ...

  8. AtCoder Regular Contest 063 F : Snuke’s Coloring 2 (线段树 + 单调栈)

    题意 小 \(\mathrm{C}\) 很喜欢二维染色问题,这天他拿来了一个 \(w × h\) 的二维平面 , 初始时均为白色 . 然后他在上面设置了 \(n\) 个关键点 \((X_i , Y_i ...

  9. cdqz2017-test10-rehearsal(CDQ分治&可持久化线段树&单调栈)

    题意: 给出n个三元组 e[i]=(si,ti,wi) 第i个三元组的价值为 Σ w[j] ,j 满足以下4个条件: 1.j<i 2.tj<ti 3.sj<si 4.不存在j< ...

随机推荐

  1. C#调用大漠插件,发送QQ和微信消息

    大漠插件就不过多介绍了,不知道的请查下百度.主要是讲解C#怎么调用大漠插件. 大漠插件提供了COM版本,C#直接点击引用,添加即可.然后注册下大漠插件到系统文件夹,注册代码如下: static str ...

  2. 金山注入浏览器默认开启上网导航 www.uu114.cn

    金山注入浏览器默认开启上网导航 www.uu114.cn 今天突然发现我的电脑所有浏览器打开后,都会默认打开一个www.uu114.cn网站,chrome.firefox和IE都中招了.经过排查,发现 ...

  3. django1.11+xadmin的搭建

    1.git clone https://github.com/sshwsfc/xadmin.git或者直接下载zip包 2..在项目根目录下建一个extra_apps的包,将xadmin源码包存放在里 ...

  4. Selenium自动化测试基础

    如有任何学习问题,可以添加作者微信:lockingfree 目录 Selenium自动化测试基础 Selenium自动化测试第一天(上) Selenium自动化测试第一天(下) Selenium自动化 ...

  5. 用IDEA编写spark的WordCount

    我习惯用Maven项目 所以用IDEA新建一个Maven项目 下面是pom文件 我粘上来吧 <?xml version="1.0" encoding="UTF-8& ...

  6. 【system.file】使用说明

    对象:system.file 说明:提供一系列针对文件操作的方法. 注意:参数中的filePath 均为相对网站根目录路径 目录: 方法 返回 说明 system.file.exists(filePa ...

  7. 【json提取器】- 提取数据的方法

    json 提取器的使用 方法 json 提取器  提取的结果   我用调试取样器进行查看

  8. Vuejs 基础与语法

    Vue 实例 创建第一个实例 {{}} 被称之为插值表达式.可以用来进行文本插值. <!DOCTYPE html> <html lang="en"> < ...

  9. Laxcus大数据管理系统2.0(6)- 第四章 数据计算

    第四章 数据计算 Laxcus所有数据计算工作都是通过网络实施.相较于集中计算,在网络间进行的数据计算更适合处理那些数据量大.复杂的.耗时长的计算任务.能够实施网络计算的前提是数据可以被分割,就是把一 ...

  10. Intro to Probabilistic Model

    概率论复习 概率(Probability) 频率学派(Frequentist):由大量试验得到的期望频率(致命缺陷:有些事情无法大量试验,例如一封邮件是垃圾邮件的概率,雷达探测的物体是一枚导弹的概率) ...