题目大意:
  一个长度为$n(n\leq10^6)$的字符串,每一位只会是$p$或$j$。你需要取出一个子串$S$(从左到右或从右到左一个一个取出),使得不管是从左往右还是从右往左取,都保证每时每刻已取出的$p$的个数不小于$j$的个数。你需要最大化$|S|$。

思路:
  令$p$为$1$,$j$为$-1$。用$sum[i]$表示$1\sim i$的前缀和,则题目所求相当于找到一个最长的区间$[l,r]$,满足$\forall i\in[l,r],sum[l-1]\le sum[i]\le sum[r]$。
  这也就意味着对于一个满足条件的区间$[l,r]$,$sum[l-1]$为最小值,$sum[r]$为最大值。
  预处理每一个位置$i$能扩展到的最左端点$left[i]$和最右端点$right[i]$。答案相当于找到一个区间$[l,r]$使得$left[r]\le l,right[l]\ge r$。将点按照$right[i]$排序,枚举对应的$i$作为$l$。用树状数组在每个$left[i]$对应的位置上维护最大的$i$。右端点$r$就是当前加入线段树且$left[i]\le l$的点中,对应的$i$的最大值。

 #include<cstdio>
#include<cctype>
#include<climits>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
inline char getalpha() {
register char ch;
while(!isalpha(ch=getchar()));
return ch;
}
const int N=1e6+;
int n,a[N],pos[N*],left[N],right[N],seq[N];
inline bool cmp(const int &a,const int &b) {
return right[a]<right[b];
}
class FenwickTree {
private:
int val[N];
int lowbit(const int &x) const {
return x&-x;
}
public:
void modify(int p,const int &x) {
for(;p<=n;p+=lowbit(p)) {
val[p]=std::max(val[p],x);
}
}
int query(int p) const {
int ret=;
for(;p;p-=lowbit(p)) {
ret=std::max(ret,val[p]);
}
return ret;
}
};
FenwickTree t;
int main() {
n=getint();
for(register int i=;i<=n;i++) {
seq[i]=i;
a[i]=getalpha()=='p'?:-;
}
std::fill(&pos[],&pos[N*],-);
for(register int i=,sum=a[];i<=n;sum+=a[++i]) {
left[i]=pos[sum+N+]+;
pos[sum+N]=i;
}
std::fill(&pos[],&pos[N*],n+);
for(register int i=n,sum=a[n];i>=;sum+=a[--i]) {
right[i]=pos[sum+N+]-;
pos[sum+N]=i;
}
int ans=;
std::sort(&seq[],&seq[n]+,cmp);
for(register int i=,j=;i<=n;i++) {
const int l=seq[i];
if(a[l]==-) continue;
for(;j<=right[l];j++) t.modify(left[j],j);
const int r=t.query(l);
ans=std::max(ans,r-l+);
}
printf("%d\n",ans);
return ;
}

[POI2014]Salad Bar的更多相关文章

  1. 【BZOJ】3521: [Poi2014]Salad Bar

    题意 长度为\(n(1 \le n \le 1000000)\)的\(01\)字符串.找一个最长的连续子串\(S\),使得不管是从左往右还是从右往左取,都保证每时每刻已取出的\(1\)的个数不小于\( ...

  2. bzoj3521: [Poi2014]Salad Bar

    Description 有一个长度为n的字符串,每一位只会是p或j.你需要取出一个子串S(从左到右或从右到左一个一个取出),使得不管是从左往右还是从右往左取,都保证每时每刻已取出的p的个数不小于j的个 ...

  3. BZOJ3521 [Poi2014]Salad Bar 【线段树 + 单调栈】

    题目链接 BZOJ3521 题解 容易想到用前缀和搞 如果我们令\(p\)为\(1\),\(j\)为\(-1\),记前缀和为\(s[i]\) 我们就是要找到一段区间\([l,r]\),使得 \[\fo ...

  4. 【思维题 单调栈】loj#2430. 「POI2014」沙拉餐厅 Salad Bar

    t老师的做法好神…… 题目描述 桌面上有 n 个水果,分别是苹果和橘子.Bytea需要从水果中选择连续的一个区间,并从左到右或从右到左拿水果,且过程中橘子的数量必须始终不小于苹果的数量.求最长的区间大 ...

  5. 【LOJ】#2430. 「POI2014」沙拉餐厅 Salad Bar

    题解 波兰人的j是苹果,p是橘子 还真是跟中国过不去啊= =写的时候很难受 我们先求出每个点作为起点,能延伸到的最大长度,这个可以处理成前缀和,查询一下区间最小值是不是小于0,用st表实现,如果区间最 ...

  6. LOJ2430:[POI2014]沙拉餐厅Salad Bar——题解

    https://loj.ac/problem/2430 是的我BZOJ又没卡过……懒得卡了. 参考:https://blog.csdn.net/zqh_wz/article/details/52887 ...

  7. P3564 [POI2014]BAR-Salad Bar

    传送门 我是来帮加藤大佬写题解的--全世界都没找到加藤大佬写法的说明--很难受-- 首先我们把\(p\)看成\(1\),\(j\)看成\(-1\),一个区间满足条件就意味着这个区间的所有前缀和都大于等 ...

  8. POI2014题解

    POI2014题解 [BZOJ3521][Poi2014]Salad Bar 把p当作\(1\),把j当作\(-1\),然后做一遍前缀和. 一个合法区间\([l,r]\)要满足条件就需要满足所有前缀和 ...

  9. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

随机推荐

  1. Oracle 学习---- 练习语法 循环( loop end loop; for ;while; if elsif end if )

    /*--set serveroutput on;declare mynum number(3) :=0; tip varchar2(10):='结果是 ';begin mynum:=10+100; d ...

  2. markdown备忘

    文章主要(99%)参考自:markdown基本语法 这是二级标题 这是加粗的文字 这是倾斜的文字` 这是引用的内容 这是引用的内容 以下是分割线: 超链接 列表内容1 列表内容2 列表内容3 1.列表 ...

  3. (转\整)UE4游戏优化 多人大地型游戏的优化(一)游戏线程的优化

    施主分享随缘,评论随心,@author:白袍小道 小道暗语: 1.因为小道这里博客目录没自己整,暂时就用随笔目录结构,所以二级目录那啥就忽略了.标题格式大致都是(原or转) 二级目录 (标题) 2.因 ...

  4. HDU 4741 Save Labman No.004 ( 三维计算几何 空间异面直线距离 )

    空间异面直线的距离直接套模板. 求交点:求出两条直线的公共法向量,其中一条直线与法向量构成的平面 与 另一条直线 的交点即可.还是套模板o(╯□╰)o 1.不会有两条线平行的情况. 2.两条直线可能相 ...

  5. stack,heap的区别

    一个由C/C++编译的程序占用的内存分为以下几个部分    1.栈区(stack)—   由编译器自动分配释放   ,存放函数的参数值,局部变量的值等.其    操作方式类似于数据结构中的栈.    ...

  6. Java String.intern()_学习笔记

    参考:https://www.jianshu.com/p/0d1c003d2ff5 String.intern() String.intern()是native方法,底层调用c++中的StringTa ...

  7. GIS专业分析方法(待更新)

    遗传算法 核密度估计 http://blog.163.com/zhuandi_h/blog/static/1802702882012111092743556/ http://blog.csdn.net ...

  8. hdu 1597 find the nth digit (数学)

    find the nth digit Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  9. 一步步制作RPM包

    一步步制作RPM包 来源 http://blog.51cto.com/laoguang/1103628 一.RPM制作步骤 我们在企业中有的软件基本都是编译的,我们每次安装都得编译,那怎么办呢?那就根 ...

  10. Kali安装到移动硬盘或者U盘中~Linux系通用方法(包括Android)

    0.1.保证这个服务必须启动(虚拟机服务最好都启动) 0.2.看看U盘接口类型是否对应 1.安装第一步 2.安装第二步,选择kali镜像 3.设置存放位置(上面的名字无所谓,最后不会用它的,虚拟机只是 ...