【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行每行一个字符串 ...
随机推荐
- MapReduce中的map个数
在map阶段读取数据前,FileInputFormat会将输入文件分割成split.split的个数决定了map的个数.影响map个数(split个数)的主要因素有: 1) 文件的大小.当块(dfs. ...
- apache服务器php程序
1.全是.php结尾的.如何首页是index 2.安装完apache,如果输入 http://localhost:50/ 若出现 it works ,代表apache运作正常
- Java基础知识强化之网络编程笔记02:Socket通信原理图解
1. Socket (1)Socket套接字 网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字 (2)Socket原理机制: • 通信两端都有Socket. • 网 ...
- php递归创建目录
/** * 递归创建目录 * @param [string] $path [创建的目录] * @return [type] [description] */ function mk_Dir($path ...
- Android手势解锁, 九宫格解锁
给大家介绍一个很好用的手势解锁控件ShapleLocker, 废话不多先上效果图: 这是一个第三方库, 可自己根据UI需求替换图标: 圆圈, 小箭头等等.. github地址: http://pane ...
- wamp5.2 升级到wamp5.3 (转载)
1. 停止WAMP服务器. 2. 去网站windows.php.net 下载php5.3.5 the VC6 Thread Safe build. 不要下载THE INSTALLER. 3. 在 ...
- npm 好用工具 for 前端
1. caniuse npm install -g caniuse-cmd
- asp.net treeview控件无刷新选择和删除节点的ajax方法
转载 http://blog.csdn.net/luq885/article/details/1621681 如果节点被选择的话,节点所在的td的class属性就会被设置为TreeView1_1. ...
- 【实习记】2014-08-23网络安全XSS与CSRF总结
XSS:脚本中的不速之客XSS:跨站脚本(Cross-site scripting)CSRF:冒充用户之手CSRF:跨站请求伪造(Cross-site request forgery) 谷歌搜 ...
- ubuntu14.04.1 LTS 64bits较快的更新源
网上关于ubuntu更新源的帖子一大堆,但是我使用网易源的时候,执行sudo apt-get update命令的时候,总是在最后几步出现hash校验的问题,虽然没什么大的影响,但是对于患有强迫症晚期综 ...