【BZOJ4384】[POI2015]Trzy wieże

Description

给定一个长度为n的仅包含'B'、'C'、'S'三种字符的字符串,请找到最长的一段连续子串,使得这一段要么只有一种字符,要么有多种字符,但是没有任意两种字符出现次数相同。

Input

第一行包含一个正整数n(1<=n<=1000000),表示字符串的长度。
第二行一个长度为n的字符串。

Output

包含一行一个正整数,即最长的满足条件的子串的长度。

Sample Input

9
CBBSSBCSC

Sample Output

6

HINT

选择BSSBCS这个子串。

题解:挺吓人的一道题~

只有一种颜色的情况直接处理,下面只说多种颜色的情况。

我们对于每个颜色维护前缀和xi,yi,zi,然后将子串和变成前缀相减。一段区间中没有两种颜色颜色相同,即这两端点的xi-yi,yi-zi,xi-zi都不相同。于是这就变成了一个类似三维偏序的问题。

先按x排序干掉一维,然后用两个以y为下标的树状数组干掉一维,最后一维怎么办呢?我们对于树状数组的每个节点维护位置的最小值,最小值的z值,以及位置的次小值,要求最小值和次小值的z不能相同。还有最大值。然后查询时用最小值或次小值更新答案,就没了、、、

最后还卡了一发常数才过~

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1000010;
int n,ans,sum;
char str[maxn];
struct node
{
int x,y,z,v;
}p[maxn];
bool cmp(const node &a,const node &b)
{
return a.x<b.x;
}
int a1[maxn<<1],a2[maxn<<1],b1[maxn<<1],b2[maxn<<1],c1[maxn<<1],c2[maxn<<1],d1[maxn<<1],d2[maxn<<1];
inline int max(int a,int b) {return a>b?a:b;}
inline void updata(int x)
{
register int i,z=p[x].z,v=p[x].v;
for(i=p[x].y;i<=2*n+1;i+=i&-i)
{
if(v>p[a1[i]].v)
{
if(z!=p[a1[i]].z) a2[i]=a1[i];
a1[i]=x;
}
else if(z!=p[a1[i]].z&&v>p[a2[i]].v) a2[i]=x;
if(v<p[c1[i]].v)
{
if(z!=p[c1[i]].z) c2[i]=c1[i];
c1[i]=x;
}
else if(z!=p[c1[i]].z&&v<p[c2[i]].v) c2[i]=x;
}
for(i=p[x].y;i;i-=i&-i)
{
if(v>p[b1[i]].v)
{
if(z!=p[b1[i]].z) b2[i]=b1[i];
b1[i]=x;
}
else if(z!=p[b1[i]].z&&v>p[b2[i]].v) b2[i]=x;
if(v<p[d1[i]].v)
{
if(z!=p[d1[i]].z) d2[i]=d1[i];
d1[i]=x;
}
else if(z!=p[d1[i]].z&&v<p[d2[i]].v) d2[i]=x;
}
}
inline void query(int x)
{
register int i,z=p[x].z,v=p[x].v;
for(i=p[x].y-1;i;i-=i&-i)
{
if(z==p[a1[i]].z) ans=max(ans,p[a2[i]].v-v);
else ans=max(ans,p[a1[i]].v-v);
if(z==p[c1[i]].z) ans=max(ans,v-p[c2[i]].v);
else ans=max(ans,v-p[c1[i]].v);
}
for(i=p[x].y+1;i<=2*n+1;i+=i&-i)
{
if(z==p[b1[i]].z) ans=max(ans,p[b2[i]].v-v);
else ans=max(ans,p[b1[i]].v-v);
if(z==p[d1[i]].z) ans=max(ans,v-p[d2[i]].v);
else ans=max(ans,v-p[d1[i]].v);
}
}
int main()
{
scanf("%d%s",&n,str+1);
register int i,j;
int a=0,b=0,c=0;
for(i=1;i<=n;i++)
{
a+=(str[i]=='B'),b+=(str[i]=='C'),c+=(str[i]=='S');
p[i].x=b-a,p[i].y=c-b+n+1,p[i].z=c-a,p[i].v=i;
if(str[i]==str[i-1]) sum++;
else sum=1;
ans=max(ans,sum);
}
p[0].y=n+1;
sort(p,p+n+1,cmp);
for(i=1;i<=2*n+1;i++) a1[i]=a2[i]=b1[i]=b2[i]=n+1,c1[i]=d1[i]=c2[i]=d2[i]=n+2;
p[n+1].v=-1,p[n+2].v=n+2;
for(i=0;i<=n;i=j+1)
{
for(j=i,query(j);j<n&&p[j+1].x==p[j].x;query(++j));
for(j=i,updata(j);j<n&&p[j+1].x==p[j].x;updata(++j));
}
printf("%d",ans);
return 0;
}

【BZOJ4384】[POI2015]Trzy wieże 树状数组的更多相关文章

  1. BZOJ4384 : [POI2015]Trzy wieże

    首先只有一种字符的情况可以通过双指针在$O(n)$的时间内处理完毕. 设$cnt[i][j]$表示前$i$个字符中$j$字符出现的次数,那么对于两个位置$j<i$: 如果 $cnt[i][0]- ...

  2. BZOJ_4378_[POI2015]Logistyka_树状数组

    BZOJ_4378_[POI2015]Logistyka_树状数组 Description 维护一个长度为n的序列,一开始都是0,支持以下两种操作: 1.U k a 将序列中第k个数修改为a. 2.Z ...

  3. [POI2015]LOG(树状数组)

    今天考试考了这题,所以来贡献\([POI2015]LOG\)的第一篇题解.代码略丑,调了快三个小时才调出来\(AC\)代码. 对于这种小清新数据结构题,所以我觉得树状数组才是这道题的正确打开方式. 首 ...

  4. 【BZOJ4382】[POI2015]Podział naszyjnika 堆+并查集+树状数组

    [BZOJ4382][POI2015]Podział naszyjnika Description 长度为n的一串项链,每颗珠子是k种颜色之一. 第i颗与第i-1,i+1颗珠子相邻,第n颗与第1颗也相 ...

  5. 【BZOJ4378】[POI2015]Logistyka 树状数组

    [BZOJ4378][POI2015]Logistyka Description 维护一个长度为n的序列,一开始都是0,支持以下两种操作:1.U k a 将序列中第k个数修改为a.2.Z c s 在这 ...

  6. 树状数组【洛谷P3586】 [POI2015]LOG

    P3586 [POI2015]LOG 维护一个长度为n的序列,一开始都是0,支持以下两种操作:1.U k a 将序列中第k个数修改为a.2.Z c s 在这个序列上,每次选出c个正数,并将它们都减去1 ...

  7. BZOJ4378[POI2015]Logistyka——树状数组

    题目描述 维护一个长度为n的序列,一开始都是0,支持以下两种操作:1.U k a 将序列中第k个数修改为a.2.Z c s 在这个序列上,每次选出c个正数,并将它们都减去1,询问能否进行s次操作.每次 ...

  8. 【bzoj4378】[POI2015]Logistyka 离散化+树状数组

    题目描述 维护一个长度为n的序列,一开始都是0,支持以下两种操作:1.U k a 将序列中第k个数修改为a.2.Z c s 在这个序列上,每次选出c个正数,并将它们都减去1,询问能否进行s次操作.每次 ...

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

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

随机推荐

  1. 測试赛C - Eqs(哈希)

    C - Eqs Time Limit:5000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Stat ...

  2. Microsoft Team Foundation Server 2010 安装 序列号 注册码(转载)

    安装过程: 一.安装操作系统 安装Windows 2008 R2简体中文版 二.准备安装过程中的需要的用户账户,并设置相应权限. 具体流程如下: 1.点击“开始”——“管理工具”——“计算机管理” 2 ...

  3. swiper动态加载数据滑动失效,ajax执行后swiper.js的效果消失问题

    使用swiper.js做一些动效时,如果进行了ajax,并且重新把DOM写入到HTML代码中,会导致swiper.js的特效消失的问题.原因是ajax加载后,原先new 的Swiper对象,不认识新来 ...

  4. xcode7 断点失效

    今天下了个别人的demo,运行发现断点不起作用,开始以为是xcode7的问题,因为自升级到xcode7后没怎么用,但后来尝试其它项目,发现是可以断点的,所以才认定不是xcode的问题,而是项目配置的问 ...

  5. self.navigationItem.titleView 不居中显示的问题

    自定义一个AUIView, AUIView * v=[AUIView new]; self.navigationItem.titleView = v; 在AUIView类内重写 setFrame -  ...

  6. 点滴积累【JS】---JS小功能(列表页面隔行变色)

    效果: 代码: <head runat="server"> <title></title> <script type="text ...

  7. JS事件类型详解

    一般事件 onclick IE3.N2 鼠标点击时触发 此事件 ondblclick IE4.N4 鼠标双击时触发 此事件 onmousedown IE4.N4 按下鼠标时触发 此事件 onmouse ...

  8. HTTP 用户认证

    HTTP 常见的用户认证可以分为下面三种: 基于IP,子网的访问控制(ACL) 基本用户验证(Basic Authentication) 消息摘要式身份验证(Digest Authentication ...

  9. node多项目同时运行,nginx端口监听转发

    在服务器端安装pm2 npm install npm2 -g --save 之后再项目目录下运行 pm2 start app.js 在查看进程,是否已经启动 pm2 list 多个项目,我们只要监听端 ...

  10. 修复Win10下Synaptics触摸板双指触击无法打开右键菜单的问题

    从Win8.1开始,Synaptics触摸板驱动的键值就不能正确设置,使得双指触击失效,无法打开右键菜单. 解决方法1.打开注册表:2.搜索“2FingerTapAction”,或直接定位到以下两个路 ...