【HDU3948】 The Number of Palindromes (后缀数组+RMQ)
The Number of Palindromes
Problem DescriptionNow, you are given a string S. We want to know how many distinct substring of S which is palindrome.InputThe first line of the input contains a single integer T(T<=20), which indicates number of test cases.
Each test case consists of a string S, whose length is less than 100000 and only contains lowercase letters.OutputFor every test case, you should output "Case #k:" first in a single line, where k indicates the case number and starts at 1. Then output the number of distinct substring of S which is palindrome.Sample Input3aaaaabababcdSample OutputCase #1: 4Case #2: 4Case #3: 4
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define Maxl 200010
#define INF 0xfffffff int c[Maxl];
int n,cl,l; int mymin(int x,int y) {return x<y?x:y;}
int mymax(int x,int y) {return x>y?x:y;} char s[Maxl];
void init()
{
scanf("%s",s);
l=strlen(s);cl=;
for(int i=;i<l;i++) c[++cl]=s[i]-'a'+;
c[++cl]=;
for(int i=l-;i>=;i--) c[++cl]=s[i]-'a'+;
} int sa[Maxl],rk[Maxl],Rs[Maxl],y[Maxl],wr[Maxl];
void get_sa(int m)
{
memcpy(rk,c,sizeof(rk));
for(int i=;i<=m;i++) Rs[i]=;
for(int i=;i<=cl;i++) Rs[rk[i]]++;
for(int i=;i<=m;i++) Rs[i]+=Rs[i-];
for(int i=cl;i>=;i--) sa[Rs[rk[i]]--]=i; int ln=,p=;//p表示目前有多少个不一样的rk
while(p<cl)
{
int k=;
for(int i=cl-ln+;i<=cl;i++) y[++k]=i;
for(int i=;i<=cl;i++) if(sa[i]>ln) y[++k]=sa[i]-ln;
for(int i=;i<=cl;i++)
wr[i]=rk[y[i]]; for(int i=;i<=m;i++) Rs[i]=;
for(int i=;i<=cl;i++) Rs[wr[i]]++;
for(int i=;i<=m;i++) Rs[i]+=Rs[i-];
for(int i=cl;i>=;i--) sa[Rs[wr[i]]--]=y[i]; for(int i=;i<=cl;i++) wr[i]=rk[i];
for(int i=cl+;i<=cl+ln;i++) wr[i]=;
p=,rk[sa[]]=;
for(int i=;i<=cl;i++)
{
if(wr[sa[i]]!=wr[sa[i-]]||wr[sa[i]+ln]!=wr[sa[i-]+ln]) p++;
rk[sa[i]]=p;
}
ln*=;m=p;
}
sa[]=rk[]=;
} int height[Maxl];
void get_he()
{
int k=;
for(int i=;i<=cl;i++) if(rk[i]!=)
{
int j=sa[rk[i]-];
if(k) k--;
while(c[i+k]==c[j+k]&&i+k<=cl&&j+k<=cl) k++;
height[rk[i]]=k;
}
height[]=;
} int d[Maxl][];
void rmq_init()
{
for(int i=;i<=cl;i++) d[i][]=height[i];
for(int j=;(<<j)<=cl;j++)
for(int i=;i+(<<j)-<=cl;i++)
d[i][j]=mymin(d[i][j-],d[i+(<<j-)][j-]);
} int rmq(int x,int y)
{
int t;
if(x>y) t=x,x=y,y=t;
x++;
int k=;
while((<<(k+))<=y-x+) k++;
return mymin(d[x][k],d[y-(<<k)+][k]);
} int ans;
void ffind()
{
int cnt=;ans=;
//奇
for(int i=;i<=cl-n;i++)
{
cnt=mymin(cnt,height[i]);
if(sa[i]<=l)
{
int j=rk[cl-sa[i]+];
int tem=rmq(i,j);
if(tem>cnt)
{
ans+=(tem-cnt);
cnt=tem;
}
}
}
//偶
cnt=;
for(int i=;i<=cl-n;i++)
{
cnt=mymin(cnt,height[i]);
if(sa[i]<=l)
{
int j=rk[cl-sa[i]+];
int tem=rmq(i,j);
if(tem>cnt)
{
ans+=tem-cnt;
cnt=tem;
}
}
}
} int main()
{
int T,kase=;
scanf("%d",&T);
while(T--)
{
init();
get_sa(+n);
get_he();
rmq_init();
ffind();
printf("Case #%d: %d\n",++kase,ans);
}
return ;
}
[HDU3948]
2016-07-19 09:46:16
【HDU3948】 The Number of Palindromes (后缀数组+RMQ)的更多相关文章
- spoj687 REPEATS - Repeats (后缀数组+rmq)
A string s is called an (k,l)-repeat if s is obtained by concatenating k>=1 times some seed strin ...
- 【uva10829-求形如UVU的串的个数】后缀数组+rmq or 直接for水过
题意:UVU形式的串的个数,V的长度规定,U要一样,位置不同即为不同字串 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&am ...
- POJ 3693 后缀数组+RMQ
思路: 论文题 后缀数组&RMQ 有一些题解写得很繁 //By SiriusRen #include <cmath> #include <cstdio> #includ ...
- HDU 6194 string string string(后缀数组+RMQ)
string string string Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
- Codeforces Round #422 (Div. 2) E. Liar 后缀数组+RMQ+DP
E. Liar The first semester ended. You know, after the end of the first semester the holidays beg ...
- HDU2459 后缀数组+RMQ
题目大意: 在原串中找到一个拥有连续相同子串最多的那个子串 比如dababababc中的abababab有4个连续的ab,是最多的 如果有同样多的输出字典序最小的那个 这里用后缀数组解决问题: 枚举连 ...
- hdu 2459 (后缀数组+RMQ)
题意:让你求一个串中连续重复次数最多的串(不重叠),如果重复的次数一样多的话就输出字典序小的那一串. 分析:有一道比这个简单一些的题spoj 687, 假设一个长度为l的子串重复出现两次,那么它必然会 ...
- ural 1297(后缀数组+RMQ)
题意:就是让你求一个字符串中的最长回文,如果有多个长度相等的最长回文,那就输出第一个最长回文. 思路:这是后缀数组的一种常见的应用,首先把原始字符串倒转过来,然后接在原始字符串的后面,中间用一个不可能 ...
- 【BZOJ 3473】 字符串 (后缀数组+RMQ+二分 | 广义SAM)
3473: 字符串 Description 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? Input 第一行两个整数n,k. 接下来n行每行一个字符串 ...
随机推荐
- 【转】warning C4819,该文件保存为 Unicode 格式以防止数据丢失,处理方法
以下的解决方案只是把错误给屏蔽掉而已,并不能真正解决这个警告.仅供参考! 当项目引用到外部源代码后,经常出现4819错误,警告信息如下: warning C4819: 该文件包含不能在当前代码页(93 ...
- android UI生成器
可根据选择的效果生成资源 http://jgilfelt.github.io/android-actionbarstylegenerator/#name=example&compat=sher ...
- oracle设定用户密码使用时间
强制用户定期更换密码,要怎么设置? 假设密码用10天之后必须修改,宽限期为2天: 把电脑时间往后调十天,然后登录: 系统提示用户密码两天内失效,这时把电脑系统再往后调两天,然后登录: 系统提示密码已经 ...
- android开发之国际化
国际化,听起来高大上,做起来很简单. 我们来实现一个简单的效果,让应用根据系统的语言来做不同的显示,假如android系统默认是英语,应用就以英文的形式显示,如果android系统默认是中文,则应用就 ...
- android应用一(调用WebServices)
搞了一个月的android,现学现卖,终于还是搞完了,停下来,整理思路,写写记录吧. 我们知道android访问远程数据库主要有两种协议,一种是SOAP,另外一种就是HTTP.而我们再看看WebSer ...
- 模版引擎(NVelocity)开发
在net中用模版开发,在handler中用到了大量的html代码.为解决这个问题,我可以采用模版引擎(NVelocity)进行开发.1.首先需要将NVelocity.dll文件放入项目,其次引用.2. ...
- # Day04-Android
Day04-Android 标签(空格分隔): andrroid 1.制作界面 2.在写Activity. Logcat LayoutInflate把Xml转换纯成View的工具. 自定义吐司 Lay ...
- 如何在ASP.NET 项目中使用Silverlight页面
闲来无事,想写个网站玩玩,比较懒,不想写太多的样式来美化,看中了Silverlight,样式布局比较省事,但是又不想全部都用Silverlight 来写,所以才有此一文. 其实Silverlight最 ...
- 尝试封装自己的js库
学了js,用过jquery,然后想着让自己在js这一块有更深的提高,就想尝试着封装自己的js库,偶尔就添加自己想到的功能.有参考过其他大牛封装库的方法,不懂的地方也有借鉴过,但代码还是自己想,自己理解 ...
- 视频处理简单实例 [OpenCV 笔记2]
VideoCapture是OpenCV 2.X中新增的类,提供从摄像机或视频文件捕获视频的C++接口.利用它读入视频的方法一般有两种: // method 1 VideoCapture capture ...