Codeforces 873F Forbidden Indices 字符串 SAM/(SA+单调栈)

时间:2021-08-15 14:33:01

原文链接https://www.cnblogs.com/zhouzhendong/p/9256033.html

题目传送门 - CF873F

题意

  给定长度为 $n$ 的字符串 $s$,以及给定这个字符串每一个位置是否 “禁止结尾” 的信息。

  一个字符串 $a$ 的价值为 $|a|\times f(a)$ 。

  其中 $f(a)$为 $a$ 在 $s$ 中的匹配次数(如果匹配的结尾为禁止结尾点,那么不算匹配成功)

  问在所有的字符串 $a$ 中,$\max(|a|\times f(a)$ 的值。

  $n\leq 2\times 10 ^5$

题解

  大概是好久没做 SAM 了,第一个想到的就是 SA 。其实用 SAM 做非常简单,不知道高到哪里去了……

  这里讲 SA 做法。

  首先考虑到 SA 对后缀开头点掌握的比较好,所以我们将原串翻转,把问题转化成开头禁止。

  然后对 $s$ 串跑一下 SA 。

  然后假装那些开头禁止的串不存在,就转化成一个经典的问题,直接单调栈搞定。

  至于单调栈原理,这里有一道类似的运用单调栈的例题。

  https://www.cnblogs.com/zhouzhendong/p/9026184.html

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=200005;
int n;
int SA[N],rank[N],tmp[N],height[N],tax[N];
int sum[N];
int st[N],top,pos[N];
char s[N],t[N];
void Sort(int n,int m){
for (int i=0;i<=m;i++)
tax[i]=0;
for (int i=1;i<=n;i++)
tax[rank[i]]++;
for (int i=1;i<=m;i++)
tax[i]+=tax[i-1];
for (int i=n;i>=1;i--)
SA[tax[rank[tmp[i]]]--]=tmp[i];
}
bool cmp(int rk[],int x,int y,int w){
return rk[x]==rk[y]&&rk[x+w]==rk[y+w];
}
void Suffix_Array(char s[],int n){
memset(SA,0,sizeof SA);
memset(tmp,0,sizeof tmp);
memset(rank,0,sizeof rank);
memset(height,0,sizeof height);
for (int i=1;i<=n;i++)
rank[i]=s[i],tmp[i]=i;
int m=234;
Sort(n,m);
for (int w=1,p=0;p<n;w<<=1,m=p){
p=0;
for (int i=n-w+1;i<=n;i++)
tmp[++p]=i;
for (int i=1;i<=n;i++)
if (SA[i]>w)
tmp[++p]=SA[i]-w;
Sort(n,m);
swap(rank,tmp);
rank[SA[1]]=p=1;
for (int i=2;i<=n;i++)
rank[SA[i]]=cmp(tmp,SA[i],SA[i-1],w)?p:++p;
}
for (int i=1,j,k=0;i<=n;height[rank[i++]]=k)
for (k=max(k-1,0),j=SA[rank[i]-1];s[i+k]==s[j+k];k++);
height[1]=0;
}
int main(){
scanf("%d",&n);
scanf("%s%s",s+1,t+1);
for (int i=1;i<=n/2;i++){
swap(s[i],s[n-i+1]);
swap(t[i],t[n-i+1]);
}
Suffix_Array(s,n);
for (int i=1;i<=n;i++)
if (t[SA[i]]=='1')
sum[i]=sum[i-1];
else
sum[i]=sum[i-1]+1;
LL ans=0;
for (int i=1;i<=n;i++)
if (t[i]=='0')
ans=max(ans,(LL)n-i+1);
top=1,st[top]=1,pos[top]=1;
height[n+1]=0;
for (int i=2;i<=n+1;i++){
int j=st[top],p=i;
while (height[j]>height[i]){
ans=max(ans,1LL*height[j]*(sum[i-1]-sum[pos[top]-2]));
p=pos[top];
j=st[--top];
}
st[++top]=i,pos[top]=p;
}
printf("%I64d",ans);
return 0;
}

  

Codeforces 873F Forbidden Indices 字符串 SAM/(SA+单调栈)的更多相关文章

  1. Codeforces 1073G Yet Another LCP Problem &dollar;SA&dollar;&plus;单调栈

    题意 给出一个字符串\(s\)和\(q\)个询问. 每次询问给出两个长度分别为\(k,l\)的序列\(a\)和序列\(b\). 求\(\sum_{i=1}^{k}\sum_{j=1}^{l}lcp(s ...

  2. CodeForces 873F Forbidden Indices 后缀数组

    忘了当时怎么做的了,先把代码贴上,保存一下后缀数组模板. #include <cstdio> #include <cstring> #include <algorithm ...

  3. Codeforces 802I Fake News &lpar;hard&rpar; &lpar;SA&plus;单调栈&rpar; 或 SAM

    原文链接http://www.cnblogs.com/zhouzhendong/p/9026184.html 题目传送门 - Codeforces 802I 题意 求一个串中,所有本质不同子串的出现次 ...

  4. luogu2178&sol;bzoj4199 品酒大会 &lpar;SA&plus;单调栈&rpar;

    他要求的就是lcp(x,y)>=i的(x,y)的个数和a[x]*a[y]的最大值 做一下后缀和,就只要求lcp=i的了 既然lcp(x,y)=min(h[rank[x]+1],..,[h[ran ...

  5. BZOJ3238 &lbrack;Ahoi2013&rsqb;差异 SA&plus;单调栈

    题面 戳这里 题解 考虑把要求的那个东西拆开算,前面一个东西像想怎么算怎么算,后面那个东西在建出\(height\)数组后相当于是求所有区间\(min\)的和*2,单调栈维护一波即可. #includ ...

  6. poj 3415 Common Substrings【SA&plus;单调栈】

    把两个串中间加一个未出现字符接起来,然后求SA 然后把贡献统计分为两部分,在排序后的后缀里,属于串2的后缀和排在他前面属于串1的后缀的贡献和属于串1的后缀和排在他前面属于串2的后缀的贡献 两部分分别作 ...

  7. 洛谷4248 AHOI2013差异 (后缀数组SA&plus;单调栈)

    补博客! 首先我们观察题目中给的那个求\(ans\)的方法,其实前两项没什么用处,直接\(for\)一遍就求得了 for (int i=1;i<=n;i++) ans=ans+i*(n-1); ...

  8. Codeforces 1156E Special Segments of Permutation(单调栈)

    可以用单调栈直接维护出ai所能覆盖到的最大的左右范围是什么,然后我们可以用这个范围暴力的去查询这个区间的是否有满足的点对,一个小坑点,要对左右区间的大小进行判断,只需要去枚举距离i最近的一段区间去枚举 ...

  9. Codeforces 316G3 Good Substrings 字符串 SAM

    原文链接http://www.cnblogs.com/zhouzhendong/p/9010851.html 题目传送门 - Codeforces 316G3 题意 给定一个母串$s$,问母串$s$有 ...

随机推荐

  1. &lbrack;Centos 6&rsqb;升级安装GCC&lpar;2&rpar;

    摘要 上篇文章升级了下gcc,但发现并没有起到作用. 安装 上篇文章: 升级GCC 升级之后,检查gcc版本 strings /usr/lib/libstdc++.so. | grep GLIBCXX ...

  2. banner轮播图js

    例子1: if(!$('.side_ul ul').is(":animated")){            var wli = $('.side_ul li').width()+ ...

  3. MySQL 数据库存储引擎

    简单介绍 存储引擎就是指表的类型.数据库的存储引擎决定了表在计算机中的存储方式.存储引擎的概念是MySQl的特点,而且是一个插入式的存储引擎概念.这就决定了MySQl数据库中的表可以使用不同的存储方式 ...

  4. VSPackge插件系列:简单文本编辑器的实现

    相比其它开发环境,VS的好用就不用多说了,尽管VS很人性化,但是针对具体的我们想实现的功能时,会力不从心,也许会有很多现成的插件,但是作为一名程序员,我还是喜欢自己去写一些东西,因为这样能随心所欲的想 ...

  5. xml和html之间相互转换

    一.xml转换html xml+xslt是典型的数据与表现分离的设计方式.当然,你可以直接转换成HTML,但是如果你要进行整体变化的时候,XML+XSLT的优势就体现出来了.同样的数据,因为你已经有X ...

  6. keepalived 安装和配置

    第一步:安装 yum -y install keepalived 第二步:配置 /etc/keepalived/keepalived.conf ! Configuration File for kee ...

  7. 如何让eclipse在程序修改后,点击运行可以自动保存。

    preferences>run/debug>launching里面save required dirty editors before launching选always就自动保存咯选pro ...

  8. 不使用Math&period;random实现随机数

    不使用Math.random实现随机数 var rand = (function(){ var today = new Date(); var seed = today.getTime(); func ...

  9. Spring Boot 2&period;0 教程 &vert; AOP 切面统一打印请求日志

    欢迎关注微信公众号: 小哈学Java 文章首发于个人网站 https://www.exception.site/springboot/spring-boot-aop-web-request 本节中,您 ...

  10. UnderWater&plus;SDN论文之五

    Underwater Sensor Networks with Mobile Agents: Experience from the Field Source: LNICST 2013 论文是来自两个 ...