首先只有一种字符的情况可以通过双指针在$O(n)$的时间内处理完毕。

设$cnt[i][j]$表示前$i$个字符中$j$字符出现的次数,那么对于两个位置$j<i$:

如果

$cnt[i][0]-cnt[j][0]\neq cnt[i][1]-cnt[j][1]$

$cnt[i][0]-cnt[j][0]\neq cnt[i][2]-cnt[j][2]$

$cnt[i][1]-cnt[j][1]\neq cnt[i][2]-cnt[j][2]$

均成立,即

$cnt[i][0]-cnt[i][1]\neq cnt[j][0]-cnt[j][1]$

$cnt[i][0]-cnt[i][2]\neq cnt[j][0]-cnt[j][2]$

$cnt[i][1]-cnt[i][2]\neq cnt[j][1]-cnt[j][2]$

均成立的话,那么就可以用$i-j$去更新答案。

设$b[i]=cnt[i][0]-cnt[i][1],c[i]=cnt[i][0]-cnt[i][2],d[i]=cnt[i][1]-cnt[i][2]$。

将所有位置按$b$从小到大排序,按$c$维护树状数组,每个区间维护$d$不同的$j$的最小值、次小值、最大值、次大值即可。

时间复杂度$O(n\log n)$。

#include<cstdio>
#define N 1000010
int n,m,i,j,D,cnt[3],col,b[N],c[N],d[N],g[N<<1],nxt[N],v[N<<1],ans;char a[N];
struct P{
int mi0,mi1,ma0,ma1;
P(){mi0=mi1=ma0=ma1=-1;}
void up(){
if(mi0<0){mi0=ma0=j;return;}
if(j<mi0){
if(D!=d[mi0])mi1=mi0;
mi0=j;
}else if((mi1<0||j<mi1)&&D!=d[mi0])mi1=j;
if(j>ma0){
if(D!=d[ma0])ma1=ma0;
ma0=j;
}else if(j>ma1&&D!=d[ma0])ma1=j;
}
}T[N];
inline int id(char x){
if(x=='B')return 0;
if(x=='C')return 1;
return 2;
}
inline void up(int a){if(ans<a)ans=a;}
inline void addedge(int x,int y){nxt[y]=g[x];g[x]=y;}
inline void ins(int x){for(;x<=m;x+=x&-x)T[x].up();}
inline void ask(int x){
for(;x;x-=x&-x){
P*t=T+x;
if(~t->mi0){
if(D!=d[t->mi0])up(j-t->mi0);else if(~t->mi1)up(j-t->mi1);
if(D!=d[t->ma0])up(t->ma0-j);else if(~t->ma1)up(t->ma1-j);
}
}
}
inline void add(int x){if(!cnt[x])col++;cnt[x]++;}
inline void del(int x){cnt[x]--;if(!cnt[x])col--;}
int main(){
scanf("%d%s",&n,a+1);
for(i=1;i<=n;i++){
cnt[a[i]=id(a[i])]++;
b[i]=cnt[0]-cnt[1],c[i]=cnt[0]-cnt[2],d[i]=cnt[1]-cnt[2];
}
for(i=0;i<=n+n;i++)g[i]=-1;
for(i=0;i<=n;i++)addedge(b[i]+n,i),v[c[i]+=n+1]=1;
for(i=1;i<=n+n+1;i++)v[i]+=v[i-1];
for(i=0;i<=n;i++){
c[i]=v[c[i]];
if(c[i]>m)m=c[i];
}
for(i=0;i<=n+n;i++){
for(j=g[i];~j;j=nxt[j])D=d[j],ask(c[j]-1);
for(j=g[i];~j;j=nxt[j])D=d[j],ins(c[j]);
}
for(i=0;i<=n;i++)c[i]=m-c[i]+1;
for(i=1;i<=m;i++)T[i]=P();
for(i=0;i<=n+n;i++){
for(j=g[i];~j;j=nxt[j])D=d[j],ask(c[j]-1);
for(j=g[i];~j;j=nxt[j])D=d[j],ins(c[j]);
}
for(i=0;i<3;i++)cnt[i]=0;
for(i=j=1;i<=n;up(i-j+1),i++)for(add(a[i]);col>1;del(a[j++]));
return printf("%d",ans),0;
}

  

BZOJ4384 : [POI2015]Trzy wieże的更多相关文章

  1. 【BZOJ4384】[POI2015]Trzy wieże 树状数组

    [BZOJ4384][POI2015]Trzy wieże Description 给定一个长度为n的仅包含'B'.'C'.'S'三种字符的字符串,请找到最长的一段连续子串,使得这一段要么只有一种字符 ...

  2. BZOJ 4384: [POI2015]Trzy wieże

    4384: [POI2015]Trzy wieże Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 217  Solved: 61[Submit][St ...

  3. [POI2015]Trzy wieże

    [POI2015]Trzy wieże 题目大意: 给定一个长度为\(n(n\le10^6)\)的仅包含'B'.'C'.'S'三种字符的字符串,请找到最长的一段连续子串,使得在这一段内出现过的所有字符 ...

  4. POI2015题解

    POI2015题解 吐槽一下为什么POI2015开始就成了破烂波兰文题目名了啊... 咕了一道3748没写打表题没什么意思,还剩\(BZOJ\)上的\(14\)道题. [BZOJ3746][POI20 ...

  5. [Poi2015]

    [POI2015]Łasuchy 一看以为是sb题 简单来说就是每个人获得热量要尽量多 不能找别人 首先这道题好像我自己找不到NIE的情况 很容易想到一个优化 如果一个数/2>另一个数 那么一定 ...

  6. bzoj AC倒序

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

  7. poi2015 bzoj4377-4386训练

    就按时间顺序写吧 完成度:10/10 3.30 bzoj4385 首先一定是删去连续d个数,然后枚举终点,起点显然有单调性,用单调队列乱搞搞就可以啦 bzoj4378 首先才结论:可行当且仅当把所有大 ...

  8. BZOJ 4385: [POI2015]Wilcze doły

    4385: [POI2015]Wilcze doły Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 648  Solved: 263[Submit][ ...

  9. Bzoj 3747: [POI2015]Kinoman 线段树

    3747: [POI2015]Kinoman Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 553  Solved: 222[Submit][Stat ...

随机推荐

  1. Swift - 语言指南,来自github学习

    @SwiftLanguage 更新于 2016-6-6,更新内容详见 Issue 55.往期更新回顾详见<收录周报> 这份指南汇集了 Swift 语言主流学习资源,并以开发者的视角整理编排 ...

  2. PHP面向对象——静态属性和静态方法

    静态属性 所谓静态属性,也就是这个属性对于这个类来说是唯一的,不管有多少个对象,只要它引用了一个静态对象,那么这些对象引用出来的值肯定是同一个. 静态变量不能使用->这种箭头符号,而是使用::这 ...

  3. jq点击和鼠标移上效果以及一个等号"=" 二个等号"==" 三个等号"===" 的区别

    <body> <div class="a" bs='1' style="width:100px; height:30px; border:1px sol ...

  4. php重修

    阅读顺序: http://www.laruence.com/2008/08/11/147.html  深入浅出php http://www.laruence.com/2008/06/18/221.ht ...

  5. JavaScript - 基本概念

    相等操作符 == 和 != 是先转换再比较 === 和 !== 是直接比较,不经过转换 中文翻译上来说叫做相等和全等.类型转换简单的概括就是高级转低级,比如说布尔字符串转数字,对象取值再转.相等比较有 ...

  6. android 入门-android自定义控件

    第一种:继承View 实现自己的属性 <com.cc.imagewithmarkersample.MyView android:id="@+id/myviewid" andr ...

  7. HR外包系统 - 员工项目 薪资项目 考勤项目 -管理

    项目管理-包括员工项目 薪资项目 考勤项目 一 后台总公司定义项目-前台分公司选择项目,定义别名-分公司客户选择员工项目,定义别名 分公司下面-新建薪资类别-薪资类别下面选择要的薪资和考勤项目. 二 ...

  8. C++重载覆盖隐藏

    写一个程序,各写出重载覆盖 1 // // main.cpp // 2013-7-17作业2 // // Created by 丁小未 on 13-7-17. // Copyright (c) 201 ...

  9. 通过ajax访问Tomcat服务器web service接口时出现No 'Access-Control-Allow-Origin' header问题的解决办法

    问题描述 通过ajax访问Web服务器(Tomcat7.0.42)中的json web service接口的时候,报以下跨域问题: XMLHttpRequest cannot load http:// ...

  10. sql优化建议

    背景:        在北京工作期间,我们做应用开发的和后台数据库的联系非常大,我们经常在一起讨论存储过程或者是sql性能优化的事情来降低应用运行时的时间,提高性能,经过和数据库方面的工程师的一些讨论 ...