牛客多校第四场 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 ...
随机推荐
- Python脚本的name
- Spring mvc Hello World
Spring mvc Hello World 添加依赖 <dependency> <groupId>org.springframework</groupId> &l ...
- VS2017 打包(详细)
1.安装打包插件:Microsoft Visual Studio 2017安装程序项目 2.联机查找下面的组件,然后安装,重启VS,进行插件安装 3.新建安装项目,另外,有些人可能会想这么多安装类 ...
- centos8 安装vmware需要的内核头文件 kernel-headers.
centos8 安装vmware需要的内核头文件 kernel-headers. uname -r (查看内核版本) rpm -qa kernel-headers (查看kernel-headers版 ...
- Algo: Binary search
二分查找的基本写法: #include <vector> #include <iostream> int binarySearch(std::vector<int> ...
- 三种Spring加载机制
方法一. 在main方法中启动Spring ApplicationContext ac = new XmlApplicationContext("applicationContext.xml ...
- leetcode-第11场双周赛-5089-安排会议日程
题目描述: 自己的提交: class Solution: def minAvailableDuration(self, slots1: List[List[int]], slots2: List[Li ...
- Java 导出excel进行换行
在导出excel 的时候,如果原始文字中含有 \n 字符,生成的excel中 会生成 _0040_ 字样的乱码, 如果把 \n 替换为<br/>,excel不会识别成换行符 excel 认 ...
- bzoj1011题解
[解题思路] 这题解法很多,我也不知道标算是什么..这简直就是大放水啊.. 网上流传的乱搞法,对于小范围内(假设为[1,l]∩N)暴力,大范围内估算. 我写这题时还是写P的?!..但是我看不懂我当时写 ...
- poj1637Sightseeing tour
传送门 网络流解混合图欧拉回路,以前xy讲过,但是我一直没写. 把无向边随意定向,每个点权值为出度减入度,权值为奇数无解,权值大于0的从s向其连权值/2的边,小于0的向t连-权值/2的边,原图中无向图 ...