这个回文自动机的板有问题,它虽然能过这道题,但是在计算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 后缀自动机/回文自动机的更多相关文章

  1. 2019牛客多校第四场 I题 后缀自动机_后缀数组_求两个串de公共子串的种类数

    目录 求若干个串的公共子串个数相关变形题 对一个串建后缀自动机,另一个串在上面跑同时计数 广义后缀自动机 后缀数组 其他:POJ 3415 求两个串长度至少为k的公共子串数量 @(牛客多校第四场 I题 ...

  2. 牛客多校第四场sequence C (线段树+单调栈)

    牛客多校第四场sequence C (线段树+单调栈) 传送门:https://ac.nowcoder.com/acm/contest/884/C 题意: 求一个$\max {1 \leq l \le ...

  3. 牛客多校第四场 F Beautiful Garden

    链接:https://www.nowcoder.com/acm/contest/142/F来源:牛客网 题目描述 There's a beautiful garden whose size is n ...

  4. 牛客多校第四场 G Maximum Mode

    链接:https://www.nowcoder.com/acm/contest/142/G来源:牛客网 The mode of an integer sequence is the value tha ...

  5. 2019牛客多校第四场 A meeting

    链接:https://ac.nowcoder.com/acm/contest/884/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他语言10485 ...

  6. 2019年牛客多校第四场 B题xor(线段树+线性基交)

    题目链接 传送门 题意 给你\(n\)个基底,求\([l,r]\)内的每个基底是否都能异或出\(x\). 思路 线性基交板子题,但是一直没看懂咋求,先偷一份咖啡鸡板子写篇博客吧~ 线性基交学习博客:传 ...

  7. 牛客多校第四场 A Ternary String

    题目描述 A ternary string is a sequence of digits, where each digit is either 0, 1, or 2. Chiaki has a t ...

  8. 牛客多校第四场 J.Hash Function(线段树优化建图+拓扑排序)

    题目传送门:https://www.nowcoder.com/acm/contest/142/J 题意:给一个hash table,求出字典序最小的插入序列,或者判断不合法. 分析: eg.对于序列{ ...

  9. 2018牛客多校第四场 J.Hash Function

    题意: 给出一个已知的哈希表.求字典序最小的插入序列,哈希表不合法则输出-1. 题解: 对于哈希表的每一个不为-1的数,假如他的位置是t,令s = a[t]%n.则这个数可以被插入当且仅当第s ~ t ...

随机推荐

  1. 2019-9-18-WPF-客户端开发需要知道的触摸失效问题

    title author date CreateTime categories WPF 客户端开发需要知道的触摸失效问题 lindexi 2019-09-18 15:30:38 +0800 2019- ...

  2. session之memcache

    nginx服务器配置:192.168.200.111[root@nginx ~]# hostname nginx[root@nginx ~]# bash[root@nginx ~]# vim /usr ...

  3. 用Cygwin实现在window环境下使用Linux命令-nohup 来后台运行程序

    1.安装Cygwin 下载 cygdrive-选择64或32位   http://www.cygwin.com/ 注:可以百度搜索安装步骤 2.配置它的环境变量 添加到path路径中 3.cmd  执 ...

  4. No parser no filepath given问题解决

    关于 vue 项目 run dev 的时候,控制台警告: No parser and no filepath given, using 'babylon' the parser now but thi ...

  5. Android中onTouch方法的执行过程以及和onClick执行发生冲突的解决办法

    $*********************************************************************************************$ 博主推荐 ...

  6. 字符串hash+回文树——hdu6599

    拖了很久才补的回文树,感觉网上的博客都是一个做法..回文树统计不同种类的回文串出现次数,然后用字符串hash来判每个回文子串是否符合要求 #include<bits/stdc++.h> u ...

  7. 排列+函数映射——hdu6038好题

    /* 引理:[0,n-1]的排列,i向a[i]连边,那么每个数必定在一个环中 所以数组a可以分割成一些环,数组b也可以分割成一些环 先讨论a的一个环 a[a1]=a2 a[a2]=a3 a[a3]=a ...

  8. 一次Spring Transactional嵌套事务使用不同的rollbackFor的分析

    起因: 项目期间由于一次异常回滚问题,发现自己在事务知识方面知识的遗漏,趁着这次机会,做了几次rollbackFor的测试. 测试:   现在有两个事务,事务oute包含事务Inner.事务A回滚规则 ...

  9. hdu多校第一场1004(hdu6581)Vacation 签到

    题意:有n+1辆车,每辆车都有一定的长度,速度和距离终点的距离,第1-n辆车在前面依次排列,第0辆车在最后面.不允许超车,一旦后车追上前车,后车就减速,求第0辆车最快什么时候能到达终点? 思路:对于每 ...

  10. 谈谈E语言

    基于中国文化底蕴的编程语言,  绝对不是E语言那个样子. 基于中文的编程,必将是计算机届的一次原子爆炸!