hdu5371(O(n)求回文子串的相关问题)
来源:互联网 发布:视频配音软件 编辑:程序博客网 时间:2024/06/13 14:17
题意:
给出一个最多有10^5次方个数字的序列,找出其中最长的N-sequence的长度。N-sequence的定义如下:
找出原串中的一个连续的子串,分成相等的三部分,第一部分和第二部分要形成一个回文串,第二部分和第三部分要形成一个回文串,第一部分要和第三部分相等。
思路:
我们先用manacher算法在O(n)的时间内求出所有的以第i位为回文串中心的回文串的长度,然后找出每一个回文串最长能伸展到哪一位,记录下来。然后我们枚举以i位中心的回文串(枚举i),每次我们在存好的set中找满足情况离i最远的下标,然后把i插入set,当我们枚举的i到达了某个个回文串能伸展到的最长的位置,我们要把那个回文串中点的下标从set中删除,如此往复,维护ans的最大值。
代码:
#include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<climits> #include<vector>#include<algorithm> #include<set>using namespace std; const int maxn=100050; vector<int> a;int rad[maxn*2];vector<int> vec[maxn*2];set<int> ss;void manacher() { memset(rad,0,sizeof(rad)); int n = a.size(); int i,j,k; i=0; j=1; while(i<n) { while(i-j>=0 && i+j<n && a[i-j]==a[i+j]) j++; rad[i]=j-1; k=1; while(k<=rad[i] && rad[i]-k!=rad[i-k]) { rad[i+k]=min(rad[i-k],rad[i]-k); k++; } i += k; j = max(j-k,0); }}int main() { int t; scanf("%d",&t); int cas=1; while(t--) { int n; scanf("%d",&n); a.clear(); for (int i = 0; i < n; i++) { int x; scanf("%d", &x); a.push_back(-1); a.push_back(x); } a.push_back(-1); manacher(); int len=a.size();for(int i=0;i<200040;i++)vec[i].clear(); for(int i=0;i<len;i++)if(a[i]==-1) vec[i+rad[i]].push_back(i); // for (int i = 0; i < a.size(); i++) { // printf("%2d ", i); // }puts(""); // for (int i = 0; i < a.size(); i++) { // printf("%2d ", a[i]); // }puts(""); // for (int i = 0; i < a.size(); i++) { // printf("%2d ", rad[i]); // }puts("");int ans=0;ss.clear();for(int i=0;i<len;i++){if(a[i]==-1){int findnum=i-rad[i];//printf("i=%d find=%d\n",i,findnum);set<int>::iterator iter;//for(iter=ss.begin();iter!=ss.end();iter++)//printf("%d ",*iter);//printf("\n");iter=ss.lower_bound(findnum);if(iter!=ss.end()){int nnnn=*iter;//printf("nnn=%d\n",nnnn);int rrr=min(rad[nnnn],rad[i]);rrr=min(rrr,i-nnnn);ans=max(ans,rrr/2*3);//printf("ans=%d\n------------\n",ans);}ss.insert(i);}if(vec[i].size()!=0){for(int j=0;j<vec[i].size();j++)ss.erase(vec[i][j]);}} printf("Case #%d: ",cas++); printf("%d\n",ans); } return 0; }
0 0
- hdu5371(O(n)求回文子串的相关问题)
- O(n) 求 最长回文子串
- O(n) 求 最长回文子串
- O(n)求最长回文子串
- O(n)求最长回文子串
- O(n) 求 最长回文子串
- O(n) 求 最长回文子串
- O(n) 求 最长回文子串
- O(n)时间求字符串的最长回文子串
- O(n)时间求字符串的最长回文子串
- O(n^3)、O(n^2)和O(n)求最长回文子串
- 求回文子串 O(n) manacher算法
- 求回文子串O(n) manacher 算法
- O(n)算法求最长回文子串
- O(n)时间内求最长回文子串
- Manacher算法--O(n)内求回文子串
- manacher算法 (O(n)求最长回文子串)
- manacher算法 O(n)求最长回文子串
- 异步等待的 Python 协程
- 29-HTML-01-HTML(概述&演示)
- linux中断子系统:中断号的映射与维护初始化mmap过程
- 面试-机试-编程题--剑指offer
- ubuntu下环境变量设置(java, eclipse)
- hdu5371(O(n)求回文子串的相关问题)
- Linux管道命令(pipe)之选取命令grep
- 字符集(编码格式相关)
- 图片标签img中,为什么使用alt属性没用
- 29-HTML-02-HTML(标签的操作思想)
- sunburnt 学习笔记 (三) 连接python和solr
- 8.11
- C++/STL_利用remove_if 删除vector,list,deque满足条件的元素
- cocos2d-js 查看对象内部