牛客多校第四场 I string 后缀自动机/回文自动机
这个回文自动机的板有问题,它虽然能过这道题,但是在计算size的时候会出锅!
题意:
求一个字符串中本质不同的连续子串有几个,但是某串和它反转后的字符串算一个。
题解:
要注意的是,一般字符串题中的“反转”,往往和回文串挂钩,反之亦然。
赛时最后半小时码的这道题,和队友很快发现了可以把字符串构造成s\$rev(s)这种形式。在这个串上求出本质不同的连续字串,这样正的和反的就都统计了一遍,再去掉带\$的连续子串,共len*(len+2)+1个,再除2就得出了结果。
但是我们忘了,即便这样反转了一次,回文串也只统计了一次。因此还要加上回文串的数量再除以二。
用后缀自动机求本质不同字符串数量,用回文自动机求本质不同回文串数量。
#include<iostream>
#include<cstring>
#include<cassert>
#define MAXN 400010
#define LL long long
using namespace std; char* strrev(char* str){
const int l = strlen(str);
for(int i=,j=l-;i<j;i++,j--){
swap(str[i],str[j]);
}
return str;
}
char s[MAXN];
char ss[MAXN];
int len; struct SAMNODE{
int ch[];
int len,fa;
SAMNODE(){memset(ch,,sizeof(ch));len=;}
}SAMdian[MAXN<<]; int SAMlas=,SAMtot=; void SAMadd(int c){
int p=SAMlas;int np=SAMlas=++SAMtot;
SAMdian[np].len=SAMdian[p].len+;
for(;p&&!SAMdian[p].ch[c];p=SAMdian[p].fa)SAMdian[p].ch[c]=np;
if(!p)SAMdian[np].fa=;//以上为case 1
else
{
int q=SAMdian[p].ch[c];
if(SAMdian[q].len==SAMdian[p].len+)SAMdian[np].fa=q;//以上为case 2
else
{
int nq=++SAMtot;SAMdian[nq]=SAMdian[q];
SAMdian[nq].len=SAMdian[p].len+;
SAMdian[q].fa=SAMdian[np].fa=nq;
for(;p&&SAMdian[p].ch[c]==q;p=SAMdian[p].fa)SAMdian[p].ch[c]=nq;//以上为case 3
}
}
} struct PTnode{
int len,fail,son[],siz;
PTnode(){
len=fail=;
for(int i=;i<=;i++)
son[i]=;
}
}PTdian[MAXN<<]; int PTlast,PTnum; int PTgetfail(int i,int x){
while(s[i-PTdian[x].len-]!=s[i]) {
x=PTdian[x].fail;
}
return x;
} void PTextend(int i,int x){
int cur=PTgetfail(i,PTlast);
if(!PTdian[cur].son[x]){
int now=++PTnum;
PTdian[now].len=PTdian[cur].len+;
PTdian[now].fail=PTdian[PTgetfail(i,PTdian[cur].fail)].son[x];
PTdian[cur].son[x]=now;
}
PTdian[PTdian[cur].son[x]].siz++;
PTlast=PTdian[cur].son[x];
} int main(){
scanf("%s",s);
len=strlen(s); PTlast=PTnum=;
PTdian[].len=-;
PTdian[].fail=PTdian[].fail=; for(int i=;i<len;i++){
PTextend(i,s[i]-'a');
} sprintf(ss,"%s%c",s,'z'+);
strrev(s);
// printf("%s\n",s);
// printf("%s\n",ss);
sprintf(ss+strlen(ss),"%s\0",s);
int len1=strlen(ss);
// printf("%s\n",ss); for(int i=;i<len1;i++){
SAMadd(ss[i]-'a');
} LL ans=;
for(int i=;i<=SAMtot;i++){
ans+=SAMdian[i].len-SAMdian[SAMdian[i].fa].len;
}
// printf("%d\n",ans); ans-=2LL*len++1LL*len*len;
ans+=PTnum-; assert(ans%==);
printf("%lld\n",ans/);
}
牛客多校第四场 I string 后缀自动机/回文自动机的更多相关文章
- 2019牛客多校第四场 I题 后缀自动机_后缀数组_求两个串de公共子串的种类数
目录 求若干个串的公共子串个数相关变形题 对一个串建后缀自动机,另一个串在上面跑同时计数 广义后缀自动机 后缀数组 其他:POJ 3415 求两个串长度至少为k的公共子串数量 @(牛客多校第四场 I题 ...
- 牛客多校第四场sequence C (线段树+单调栈)
牛客多校第四场sequence C (线段树+单调栈) 传送门:https://ac.nowcoder.com/acm/contest/884/C 题意: 求一个$\max {1 \leq l \le ...
- 牛客多校第四场 F Beautiful Garden
链接:https://www.nowcoder.com/acm/contest/142/F来源:牛客网 题目描述 There's a beautiful garden whose size is n ...
- 牛客多校第四场 G Maximum Mode
链接:https://www.nowcoder.com/acm/contest/142/G来源:牛客网 The mode of an integer sequence is the value tha ...
- 2019牛客多校第四场 A meeting
链接:https://ac.nowcoder.com/acm/contest/884/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他语言10485 ...
- 2019年牛客多校第四场 B题xor(线段树+线性基交)
题目链接 传送门 题意 给你\(n\)个基底,求\([l,r]\)内的每个基底是否都能异或出\(x\). 思路 线性基交板子题,但是一直没看懂咋求,先偷一份咖啡鸡板子写篇博客吧~ 线性基交学习博客:传 ...
- 牛客多校第四场 A Ternary String
题目描述 A ternary string is a sequence of digits, where each digit is either 0, 1, or 2. Chiaki has a t ...
- 牛客多校第四场 J.Hash Function(线段树优化建图+拓扑排序)
题目传送门:https://www.nowcoder.com/acm/contest/142/J 题意:给一个hash table,求出字典序最小的插入序列,或者判断不合法. 分析: eg.对于序列{ ...
- 2018牛客多校第四场 J.Hash Function
题意: 给出一个已知的哈希表.求字典序最小的插入序列,哈希表不合法则输出-1. 题解: 对于哈希表的每一个不为-1的数,假如他的位置是t,令s = a[t]%n.则这个数可以被插入当且仅当第s ~ t ...
随机推荐
- Linux 下工作用户及环境
交叉工具的安装 工具链的编译过程请参考第三部分. 1. 下载交叉工具 2.95.3 下载地址:ftp://ftp.arm.linux.org.uk/pub/armlinux/toolchain/cro ...
- Development 编程规范
{ 命名规范类命名 1)所有的类名,接口名(Protocol)均以大写字母开头,多单词组合时,后面的单词首字母大写. 类,接口名必须是有意义的,切忌使用中文拼音命名.另外所有类都要加标致前缀:“O ...
- 全球首个开放应用模型 OAM 开源
业界要闻 全球首个开放应用模型 OAM 开源 2019 年 10 月 17 日,阿里巴巴合伙人.阿里云智能基础产品事业部总经理蒋江伟(花名:小邪)在 Qcon 上海重磅宣布,阿里云与微软联合推出开放应 ...
- day 88 DjangoRestFramework学习二之序列化组件、视图组件
DjangoRestFramework学习二之序列化组件.视图组件 本节目录 一 序列化组件 二 视图组件 三 xxx 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 序列化组件 ...
- 《DSP using MATLAB》Problem 8.45
代码: %% ------------------------------------------------------------------------ %% Output Info about ...
- linux 下 CDH4.5编译
1.安装JDK JDK:我这里 安装的是jdk1.6.0_23 1.1:给文件执行的权限chmod u+x jdk-6u23-linux-x64.bin 1.2: ./jdk-6u23-linux-x ...
- Myeclipse配置tomcat和jdk
1.打开Myeclipse,Windows--preference--出现如下窗口.Browse为导入解压的tomcat路径. 2.配置jdk.使用哪个tomcat,就配置哪个tomcat下的jdk, ...
- 初识OpenCV-Python - 001
主要用代码注释来初步学习OpenCV-Python 1. 图片初使用(结合matplotlib) import cv2from matplotlib import pyplot as plt #Loa ...
- mysql 数据库基本命令
停止mysql服务:net stop mysql //管理员方式运行 启动mysql服务:net start mysql 进入数据库:mysql -u root -p 查看数据库:show ...
- arm-linux-strip 的使用
3.2.1 1. 移除所有的符号信息 [arm@localhost gcc]#cp hello hello1 [arm@localhost gcc]#armlinuxstrip strip ...