Spoj REPEATS 后缀自动机+set
REPEATS - Repeats
链接:http://www.spoj.com/problems/REPEATS
题意:求S串中某个子串连续循环次数最多的次数。
想法:
从暴力开始,枚举所有串,求出这些串的最小循环节长度,算出连续循环次数。
如何求一个串S的最小循环节长度:即next表示这个串最长后缀与前缀相等的长度,最小循环节长度=S.length-next。
KMP可以解决next,于是O(n^2)暴力求出答案。然后优化一下。
上图ans=(len+(x-y))/(x-y)。
在SAM一个节点上,以其{right}为右端点长度为[min,max]的串都相等。那么对应上图,{right}中距离最小的两个点x,y.ans=(max+|x-y|)/|x-y|。
用平衡树维护{right},再启发式合并。
总O(nlog^2n)
1 #include<cstdio> 2 #include<cstring> 3 #include<set> 4 const int len(50000),INF(200000); 5 struct SamNode{int nx[2],pre,step;}sam[len*2+10]; 6 std::set<int>RBT[len*2+10];int size[len*2+10],rt[len*2+10]; 7 std::set<int>::iterator ii,ti; 8 int top=1,root=1,now=1,last,lastson; 9 int cnt[len+10],p[len*2+10],mn[len*2+10]; 10 void insert(int x) 11 { 12 last=now;now=++top; 13 sam[now].step=sam[last].step+1; 14 size[now]=1;mn[now]=INF;rt[now]=now; 15 RBT[now].insert(sam[now].step); 16 for(;!sam[last].nx[x]&&last;last=sam[last].pre) 17 sam[last].nx[x]=now; 18 if(!last)sam[now].pre=root; 19 else 20 { 21 lastson=sam[last].nx[x]; 22 if(sam[lastson].step==sam[last].step+1)sam[now].pre=lastson; 23 else 24 { 25 sam[++top]=sam[lastson]; 26 sam[top].step=sam[last].step+1; 27 mn[top]=INF;rt[top]=top;size[top]=0; 28 sam[now].pre=sam[lastson].pre=top; 29 for(;sam[last].nx[x]==lastson&&last;last=sam[last].pre) 30 sam[last].nx[x]=top; 31 } 32 } 33 } 34 int T,n,ans;char ch[1]; 35 void swap(int &a,int &b){if(a==b)return;a^=b;b^=a;a^=b;} 36 int min(int a,int b){return a>b?b:a;} 37 int max(int a,int b){return a<b?b:a;} 38 void union_set(int x,int y) 39 { 40 if(size[rt[x]]<size[rt[y]])swap(rt[x],rt[y]); 41 int val; 42 for(ii=RBT[rt[y]].begin();ii!=RBT[rt[y]].end();ii++) 43 { 44 val=*(ii); 45 RBT[rt[x]].insert(val); 46 ti=RBT[rt[x]].find(val); 47 if(ti!=RBT[rt[x]].begin()) 48 { 49 ti--;mn[rt[x]]=min(mn[rt[x]],val-*(ti));ti++; 50 } 51 if(ti!=RBT[rt[x]].end()) 52 { 53 ti++; 54 if(ti!=RBT[rt[x]].end())mn[rt[x]]=min(mn[rt[x]],*(ti)-val); 55 } 56 size[rt[x]]++; 57 } 58 RBT[rt[y]].clear(); 59 } 60 void total() 61 { 62 for(int i=1;i<=n;i++)cnt[i]=0; 63 for(int i=1;i<=top;i++)cnt[sam[i].step]++; 64 for(int i=1;i<=n;i++)cnt[i]+=cnt[i-1]; 65 for(int i=top;i>=1;i--)p[cnt[sam[i].step]--]=i; 66 for(int i=top;i>=2;i--) 67 { 68 ans=max(ans,(sam[p[i]].step+mn[rt[p[i]]])/mn[rt[p[i]]]); 69 union_set(sam[p[i]].pre,p[i]); 70 } 71 RBT[rt[1]].clear(); 72 } 73 int main() 74 { 75 scanf("%d",&T); 76 while(T--) 77 { 78 memset(sam,0,sizeof(sam)); 79 top=1,root=1,now=1;ans=0; 80 mn[1]=INF;rt[1]=1;size[1]=0; 81 scanf("%d",&n); 82 for(int i=1;i<=n;i++) 83 { 84 scanf("%s",ch); 85 insert(ch[0]-'a'); 86 } 87 total(); 88 printf("%d\n",ans); 89 } 90 return 0; 91 }
转载于:https://www.cnblogs.com/Oncle-Ha/p/6597104.html
Spoj REPEATS 后缀自动机+set相关推荐
- SPOJ NSUBSTR(后缀自动机)
题目链接:http://www.spoj.com/problems/NSUBSTR/ 题目大意:给你一个字符串s(len(s)<=250000),求f[i](i=1...len(s)),其中f[ ...
- SPOJ LCS 后缀自动机
用后缀自动机求两个长串的最长公共子串,效果拔群.多样例的时候memset要去掉. 解题思路就是跟CLJ的一模一样啦. #pragma warning(disable:4996) #include< ...
- SPOJ 7258 (后缀自动机)
转载:http://hzwer.com/4492.html 给一个长度不超过90000的串S,每次询问它的所有不同子串中,字典序第K小的,询问不超过500个. 搞出后缀自动机 dp处理出每个点往下走能 ...
- 【后缀自动机】SPOJ 1812-LCSII
题意: 给出最多10个长度不超过100000的字符串,求他们的LCS的长度.时限是鬼畜的0.25s . 后缀自动机练习...虽然有人这么说但我并不觉得hash能过. 本题可以说是[论SAM中按step ...
- SPOJ 1812 LCS2 - Longest Common Substring II (后缀自动机)【两种做法】
SPOJ 1812 LCS2 - Longest Common Substring II (后缀自动机)[两种做法] 手动博客搬家: 本文发表于20181217 23:54:35, 原地址https: ...
- 【SPOJ】7258. Lexicographical Substring Search(后缀自动机)
http://www.spoj.com/problems/SUBLEX/ 后缀自动机系列完成QAQ...撒花..明天or今晚写个小结? 首先得知道:后缀自动机中,root出发到任意一个状态的路径对应一 ...
- 【BZOJ2780】【SPOJ】Sevenk Love Oimaster(广义后缀自动机)
Description 有n个大串和m个询问,每次给出一个字符串s询问在多少个大串中出现过. Solution 广义后缀自动机入门题. 其实就是在插入一个串后将last设为root即可. 然后统计每个 ...
- SPOJ 1812 LCS2 - Longest Common Substring II (后缀自动机、状压DP)
手动博客搬家: 本文发表于20181217 23:54:35, 原地址https://blog.csdn.net/suncongbo/article/details/85058680 人生第一道后缀自 ...
- SPOJ - NSUBSTR Substrings(后缀自动机)
题目链接:点击查看 题目大意:给出一个字符串,求出每个长度下的子串出现最多的次数 题目分析:对原串跑后缀自动机然后记录每个节点的right集合的大小就是当前节点出现的次数了,这个出现次数显然可以从子节 ...
- spoj 1811 LCS 后缀自动机
A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the s ...
最新文章
- 2022-2028年中国TFT玻璃行业市场研究及前瞻分析报告
- XCOM串口助手打印不出数据
- 两个常数的卷积为多少_卷积(Convolution)与好核函数(Good Kernel)
- 并发场景下的幂等问题——分布式锁详解
- 停止犯下这5个JavaScript风格错误
- WCF中因序列化问题引起的异常和错误。
- python3安装步骤-Mac安装python3的方法步骤
- contact form 7如何设置placeholder让提示文字显示在输入框中
- SPA单页面应用、前后端分离项目SEO优化的方法
- Android小项目:计算器
- Zoom支持自动生成字幕;SharePlay上线;Safari 更新导致大量bug |WebRTC风向
- 与编程密切相关的数学——离散数学——代数系统篇
- 白加黑加载方式_基层干部白加黑的工作方式不可取
- MATLAB2016笔记(五):进阶矩阵操作
- java培训出来的面试经历
- Siri的兄弟Viv可能带来下一个人工智能的革命
- 2021秋季开学必备数码产品!学生党的超实用好物清单
- “33岁转行软件测试还来得及吗?”怎么去转行软件测试?
- ChatGPT研究报告:AIGC带来新一轮范式转移
- Swagger注解 传参