[JZOJ4439]不是回文串
2016-05-06 22:10
309 查看
题目大意
一个只包含小写字母的字符串S,定义一个子串T出现值为|T|乘上T在S中的出现次数。求出现次数不为1的子串中最大的出现值。
|S|≤106
题目分析
SAM裸题,直接建SAM,计算即可。时间复杂度O(|S|)。
代码实现
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> using namespace std; const int N=1000500; const int S=N<<1; const int C=26; char s ; struct Node { int prt,len,size; int next[C]; }sam[S]; int tot,suf,ans; int insert(int last,int c) { int np=++tot,p=last,q; sam[np].size=1; for (sam[np].len=sam[p].len+1;p&&!sam[p].next[c];p=sam[p].prt) sam[p].next[c]=np; if (!p) sam[np].prt=1; else if (sam[p].len+1==sam[q=sam[p].next[c]].len) sam[np].prt=q; else { int nq=++tot; sam[nq]=sam[q],sam[nq].size=0,sam[nq].len=sam[p].len+1; sam[q].prt=sam[np].prt=nq; for (;p&&sam[p].next[c]==q;p=sam[p].prt) sam[p].next[c]=nq; } return np; } int id[S]; bool cmp(int x,int y) { return sam[x].len<sam[y].len; } void calc() { for (int i=1;i<=tot;i++) id[i]=i; sort(id+1,id+1+tot,cmp); for (int i=tot;i>=1;i--) if (sam[id[i]].prt) sam[sam[id[i]].prt].size+=sam[id[i]].size; for (int x=tot;x>=1;x--) if (sam[x].size>1) ans=max(ans,sam[x].size*sam[x].len); } int n; int main() { freopen("sam.in","r",stdin); freopen("sam.out","w",stdout); memset(sam,0,sizeof sam); tot=suf=1; scanf("%s",s); n=strlen(s); for (int i=0;i<n;i++) suf=insert(suf,s[i]-'a'); calc(); printf("%d\n",ans); fclose(stdin); fclose(stdout); return 0; }
相关文章推荐
- STL学习——Deque篇
- 《Hibernate学习笔记九》:多对一和一对多的关联关系
- UISenior 之 CoreData初级
- 动态内存管理
- 源代码管理工具之SVN
- runtime-对成员变量操作应用之归档和返归档
- 3月9日作业 信息系统集成专业技术知识 七道题
- opencv的dnn解析
- python 迭代器与生成器 详解
- HTTPS
- redis cluster 集群架构
- 23.二叉树中和为某一值的路径
- 矢量点乘证明
- bootstrapDialog插件集成datatables插件遇到的异常
- Linux--信号
- [bzoj3065]带插入区间K小值
- navicat 如何设置外键
- 程序员修炼之道----从小工到大家读书笔记(一)
- Android 不一样的原生分享
- 【BZOJ2653】middle,主席树(非权值线段树)维护序列和信息+二分答案