POI2014 Salad Bar

这道题的大意就是给你一个字符串,里面只含有pj,求一个最长的子串,使得从左边开始,p的个数一直比j多,从右边开始也一样.

这道题的话,一开始想歪了,就先对每个字符,算出来以它为起点往右最多能在哪里,然后再算出来以它为起点往左最多能走到哪里,这样的话,一个满足条件的子串一定满足R[l]>=r,L[r]<=lR[l]>=r,L[r],然后按照左边小的排一下序,然后就可以乱搞一下了…

就是从左往右,每到一个点就把能够穿过它的都加入到现在已有的点集中,然后在把这个点右端点以内的最右的一个找到,这就是以这个点为左端点,能够得到的最长子串了.

具体的操作的话,使用树状数组来完成的,比较麻烦吧…

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M 1000005
using namespace std;
char A[M];
int sum[M],n;
struct Bit{int Tree[M<<1];void Pl(){memset(Tree,-1,sizeof(Tree));}void Add(int x,int v){while(x<=M<<1){if(v>Tree[x])Tree[x]=v;x+=x&(-x);}}int Qu(int x){int re=-1;while(x){if(Tree[x]>re)re=Tree[x];x-=x&(-x);}return re;}
}T;
struct W{int L,R,id;bool operator <(const W &a)const{return L<a.L;}
}Q[M];
int L[M],R[M];
int main(){scanf("%d %s",&n,A+1);for(int i=1;i<=n;i++)sum[i]=sum[i-1]+(A[i]=='j'?-1:1);T.Pl();for(int i=n;i>=1;i--){Q[i].R=T.Qu(sum[i-1]+M-1);if(A[i]=='j')Q[i].R=-1;else if(Q[i].R!=-1)Q[i].R=n-Q[i].R+1;else if(Q[i].R==-1)Q[i].R=n;T.Add(sum[i]+M,n-i+1);R[i]=Q[i].R;}T.Pl();for(int i=n;i>=1;i--)sum[i]=sum[i+1]+(A[i]=='j'?-1:1);for(int i=1;i<=n;i++){Q[i].L=T.Qu(sum[i+1]+M-1);if(A[i]=='j')Q[i].L=-1;else if(Q[i].L==-1)Q[i].L=1;else Q[i].L++;T.Add(sum[i]+M,i);L[i]=Q[i].L;}for(int i=1;i<=n;i++)Q[i].id=i;T.Pl();sort(Q+1,Q+n+1);int ans=0,pos=1;while(pos<=n&&Q[pos].L==-1)pos++;for(int i=1;i<=n;i++){while(pos<=n&&Q[pos].L<=i)T.Add(Q[pos].id,Q[pos].id),pos++;if(R[i]!=-1){int tmp=T.Qu(R[i]);if(tmp!=-1&&tmp-i+1>ans)ans=tmp-i+1;}}printf("%d\n",ans);return 0;
}

改变一下前缀和,令p=1,j=-1,这样可以得到一个前缀和数组sum.

然后再继续考虑,我们可以发现,对于一个合法的区间[l,r],一定会有

sum[l]<=sum[i]<=sum[r],l<=i<=r

sum[l]
而这个前缀和又是连续的(每次都只会变化1),所以可以 O(n)O(n)地处理出每一个点下一个前缀和与它相等的点在哪里,放在nxt数组里面.

然后定义pev[i]为从i开始,最远的满足条件的字符的下标.

那么就可以解答问题了,每一次记录下上一次的pev,记为pre,然后再比较一下nxt[i-1]与pre哪一个更好,然后更新就行了.

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M 1000005
using namespace std;
char A[M];
int sum[M],nxt[M],pev[M];
int last[M];
int main(){int n,mi=0;scanf("%d %s",&n,A+1);for(int i=1;i<=n;i++){sum[i]=sum[i-1]+(A[i]=='p'?1:-1);if(sum[i]<mi)mi=sum[i];}memset(last,-1,sizeof(last));for(int i=n,x;i>=0;i--){x=sum[i]-mi;nxt[i]=last[x];last[x]=i;pev[i]=i;}int ans=0;for(int i=n,pre=n;i>=1;i--){if(A[i]=='p'){if(~nxt[i-1]&&sum[pev[nxt[i-1]]]>=sum[pre])pre=pev[nxt[i-1]];pev[i-1]=pre;int ll=pre-i+1;if(ll>ans)ans=ll;}else pre=i-1;}printf("%d\n",ans);return 0;
}

POI2014Salad Bar相关推荐

  1. iOS开发8:使用Tool Bar切换视图

    之前讨论的都是单视图应用程序,而在实际应用中,我们可能要多个视图,并根据用户的需要切换视图. iOS中几种典型的多视图程序: (1)Tab Bar Application:程序的底部有一排按钮,轻触其 ...

  2. matlab pup,matlab利用bar函数画不同颜色直方图

    matlab利用bar函数画直方图,参考文献[1]是matlab官方提供的help文档.里面提供了bar函数的基本用法,但是没有说明如何在同一张图中,为每个bar设置不同的颜色. 例子代码: myda ...

  3. android values-v21 style 报错,Android 4.4 以上实现透明导航栏和状态栏 Translucent system bar...

    第一种方式 第一种方式,需要做下面三步设置 1.在values.values-v19.values-v21的style.xml都设置一个 Translucent System Bar 风格的Theme ...

  4. 设置status bar的颜色

    statusBar显示电池电量.时间.网络部分标示的颜色只能设置两种颜色: 默认的黑色(UIStatusBarStyleDefault) 白色(UIStatusBarStyleLightContent ...

  5. 转 如何在IOS设备中去掉屏幕上的status bar

    引入 如何在IOS设备中去掉屏幕上的status bar,即:不显示设备上方的[网络.时间.电池??]条? 操作 方法一: 在-info.list项目文件中,加上"Status bar is ...

  6. Android UI开发第二十五篇——分享一篇自定义的 Action Bar

    Action Bar是android3.0以后才引入的,主要是替代3.0以前的menu和tittle bar.在3.0之前是不能使用Action Bar功能的.这里引入了自定义的Action Bar, ...

  7. Tab Bar Animation

    2019独角兽企业重金招聘Python工程师标准>>> 自定义UITabBar.自定义Tab Bar切换过程中的动画效果.用户点击某个Tab,一个小箭头会从之前的Tab上面移动到当前 ...

  8. iPhone App开发导航条(Navigation Bar)素材PSD下载

    不管是iPhone还是Android的应用App界面基本上最上方都会有个导航条(Navigation Bar).于是我决定创建此页面整理收集所有好看的适合在iPhone App应用开发中使用的导航条素 ...

  9. 技术图文:如何利用C# + Echarts 绘制 Bar Simple?

    背景 Echarts 是百度推出的一个使用 JavaScript 实现的开源可视化库. 该库提供了常规的折线图.柱状图.散点图.饼图.K线图,用于统计的盒形图,用于地理数据可视化的地图.热力图.线图, ...

最新文章

  1. 为什么博图中放置按下按钮无反应_如何更好的设计按钮
  2. android基础ui控件,Android基础——基础UI控件
  3. 【NLP】Sentence-T5|谷歌提出文本表示新SOTA
  4. dhtmlXGrid复选框点击事件
  5. NodeJS常用模块介绍
  6. bufg和bufgp_如何将自己写的verilog模块封装成IP核(一)
  7. Spring IOC(控制反转)思想笔记
  8. SQL Server复制功能 巧妙选择避开Bug
  9. JAVAEWEB实现文件的上传案例
  10. 【Python+OpenCV】Windows+Python3.6.0(Anaconda3)+OpenCV3.2.0安装配置
  11. 3.1.1 Agri-Net
  12. Android关系型数据库应用——电话(短信)黑名单 .
  13. OSChina 周二乱弹 ——流川枫与苍井空
  14. java企业员工考勤请假工资人事管理系统springboot+vue
  15. C++ 设计模式 简单工厂模式
  16. A股市股票行情实时数据最简封装API接口的python实现
  17. Java 根据贷款年限对应的不同利率计算月供
  18. Discuz被挂马的处理经验,Dz为什么会被挂马
  19. iphone热点蓝条闪烁
  20. 什么!作为程序员你连英文版的官方文档都看不懂?

热门文章

  1. 【Android Jetpack学习之旅】--> Navigation 的使用
  2. C Primer Plus 第三章编程练习一
  3. 财商教育—百万富翁的生活习惯
  4. springboot+shiro+redis+jwt实现多端登录:PC端和移动端同时在线(不同终端可同时在线)
  5. 一些多元逐步回归的注意事项
  6. python 对角阵_python-Numpy分区对角矩阵
  7. python-查找字符串
  8. rd如何撰写总体设计文档和详细设计文档
  9. stripe支付集成
  10. 最清晰的进制转换讲解 - java实现