The Number of Palindromes

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
http://acm.hdu.edu.cn/showproblem.php?pid=3948

Problem Description
Now, you are given a string S. We want to know how many
distinct substring of S which is palindrome.
 
Input
The 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.
 
Output
For 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 Input
3
aaaa
abab
abcd
 
Sample Output
Case #1: 4
Case #2: 4
Case #3: 4
 
Source
 
Recommend
xubiao   |   We have carefully selected several similar
problems for you:  3946 3947 3949 3945 3944 
 
题意:统计不同回文串的个数
首先对原串跑一遍manacher算法,处理出最长回文半径
然后枚举每一个位置
从最长的回文串开始一点一点儿往里索,hash判断这个字符串是否出现过
如果出现过,那么比它更短的肯定也出现过,结束本位置的查找,到下一个位置
 
#include<map>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define D1 28
#define D2 38
using namespace std;
const int MOD1=;
const int MOD2=;
const int MOD3=1e9+;
const int MOD4=1e9+;
char s[],a[];
int p[],len,l,ans;
int f1[],g1[];
int f2[],g2[];
int front1[MOD1+],front2[MOD2+];
int to1[],to2[];
int nxt1[],nxt2[];
int tot1,tot2;
void manacher()
{
memset(p,,sizeof(p));
int pos=,id=,x;
for(int i=;i<=len;i++)
{
if(i<pos) x=min(p[*id-i],pos-i);
else x=;
while(s[i+x]==s[i-x]) x++;
if(i+x>pos) { pos=i+x; id=i; }
p[i]=x;
}
}
int get_hash1(int l,int r)
{
int a=f1[r];
int b=1ll*f1[l-]*g1[r-l+]%MOD3;
return (b-a+MOD3)%MOD3;
}
int get_hash2(int l,int r)
{
int a=f2[r];
int b=1ll*f2[l-]*g2[r-l+]%MOD4;
return (b-a+MOD4)%MOD4;
}
void add1(int u,int v)
{
to1[++tot1]=v; nxt1[tot1]=front1[u]; front1[u]=tot1;
}
void add2(int u,int v)
{
to2[++tot2]=v; nxt2[tot2]=front2[u]; front2[u]=tot2;
}
bool find1(int u,int v)
{
for(int i=front1[u];i;i=nxt1[i])
if(to1[i]==v) return true;
return false;
}
bool find2(int u,int v)
{
for(int i=front2[u];i;i=nxt2[i])
if(to2[i]==v) return true;
return false;
}
void cal(int pos,int len)
{
for(int i=len;i>=;i--)
{
int hash1=get_hash1(pos-i+,pos+i-);
int hash2=get_hash2(pos-i+,pos+i-);
int t1=hash1%MOD1,t2=hash2%MOD2;
if(!(find1(t1,hash1)&&find2(t2,hash2)))
{
ans++;
add1(t1,hash1);
add2(t2,hash2);
}
else return;
}
}
void pre()
{
ans=tot1=tot2=;
memset(front1,,sizeof(front1));
memset(front2,,sizeof(front2));
memset(f1,,sizeof(f1));
memset(f2,,sizeof(f2));
g1[]=;
for(int i=;i<=len;i++) g1[i]=1ll*g1[i-]*D1%MOD3;
f1[]=s[];
for(int i=;i<=len;i++) f1[i]=(1LL*f1[i-]*D1+s[i]-'')%MOD3;
g2[]=;
for(int i=;i<=len;i++) g2[i]=1ll*g2[i-]*D2%MOD4;
f2[]=s[];
for(int i=;i<=len;i++) f2[i]=(1LL*f2[i-]*D2+s[i]-'')%MOD4;
}
int main()
{
int t;
scanf("%d",&t);
for(int tt=;tt<=t;tt++)
{
scanf("%s",a);
s[len=]='!';
l=strlen(a);
for(int i=;i<l;i++)
{
s[++len]='#';
s[++len]=a[i];
}
s[++len]='#';
s[len+]='&';
pre();
manacher();
for(int i=;i<=len;i++)
cal(i,p[i]);
printf("Case #%d: %d\n",tt,ans/);
}
}

hdu 3948 The Number of Palindromes的更多相关文章

  1. HDU 3948 The Number of Palindromes(Manacher+后缀数组)

    题意 求一个字符串中本质不同的回文子串的个数. $ 1\leq |string| \leq 100000$ 思路 好像是回文自动机的裸题,但是可以用 \(\text{Manacher}\) (马拉车) ...

  2. 【HDOJ】3948 The Number of Palindromes

    后缀数组求不重复回文子串数目.注意dp数组. /* 3948 */ #include <iostream> #include <sstream> #include <st ...

  3. hdu 3948 后缀数组

    The Number of Palindromes Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (J ...

  4. hdu 5898 odd-even number 数位DP

    传送门:hdu 5898 odd-even number 思路:数位DP,套着数位DP的模板搞一发就可以了不过要注意前导0的处理,dp[pos][pre][status][ze] pos:当前处理的位 ...

  5. dp --- Codeforces 245H :Queries for Number of Palindromes

    Queries for Number of Palindromes Problem's Link:   http://codeforces.com/problemset/problem/245/H M ...

  6. hdu 2665 Kth number

    划分树 /* HDU 2665 Kth number 划分树 */ #include<stdio.h> #include<iostream> #include<strin ...

  7. 【HDU3948】 The Number of Palindromes (后缀数组+RMQ)

    The Number of Palindromes Problem Description Now, you are given a string S. We want to know how man ...

  8. 【CF245H】Queries for Number of Palindromes(回文树)

    [CF245H]Queries for Number of Palindromes(回文树) 题面 洛谷 题解 回文树,很类似原来一道后缀自动机的题目 后缀自动机那道题 看到\(n\)的范围很小,但是 ...

  9. 【SPOJ】NUMOFPAL - Number of Palindromes(Manacher,回文树)

    [SPOJ]NUMOFPAL - Number of Palindromes(Manacher,回文树) 题面 洛谷 求一个串中包含几个回文串 题解 Manacher傻逼题 只是用回文树写写而已.. ...

随机推荐

  1. mysql 导入 大sql文件

    任务:第一次用mysql,需要将一个1G左右的sql文件导入: 步骤:1:安装mysql-installer-community-5.7.20.0.msi 64位安装包 2:命令行登录:  mysql ...

  2. Java标签实现分页

    Java实现标签分页 最近为了开发一个网站,里面要用分页功能,但是之前很少自己写分页标签,又不想用现成框架.所以自己参考了些资料,写了个分页例子测试了一下. 代码主要分为三个类: PageTag 分页 ...

  3. php常用方法汇总

    xml格式转成array <?php $str='<xml><node><![CDATA[content]]></node></xml> ...

  4. 为什么23种设计模式中没有MVC

    GoF (Gang of Four,四人组, <Design Patterns: Elements of Reusable Object-Oriented Software>/<设计 ...

  5. DFS中的奇偶剪枝(技巧)

    剪枝是什么,简单的说就是把不可行的一些情况剪掉,例如走迷宫时运用回溯法,遇到死胡同时回溯,造成程序运行时间长.剪枝的概念,其实就跟走迷宫避开死胡同差不多.若我们把搜索的过程看成是对一棵树的遍历,那么剪 ...

  6. 策略模式,ASP.NET实现

    策略模式,ASP.NET实现 using System; using System.Collections.Generic; using System.Linq; using System.Web; ...

  7. TCP系列32—窗口管理&流控—6、TCP zero windows和persist timer

    一.简介 我们之前介绍过,TCP报文中的window size表示发出这个报文的一端准备多少bytes的数据,当TCP的一端一直接收数据,但是应用层没有及时读取的话,数据一直在TCP模块中缓存,最终受 ...

  8. 3dContactPointAnnotationTool开发日志(四)

      没办法,为了能在寝室接着做这玩意只好又在电脑上装一个和实验室版本一样的unity了.虽然打开后UI界面还是一团糟,不过至少要的东西都在,又手动调了调UI界面.   然后把旋转视角功能加上了.鼠标右 ...

  9. Unity3d学习日记(三)

      使用Application.LoadLevel(Application.loadedLevel);来重新加载游戏scene的方法已经过时了,我们可以使用SceneManager.LoadScene ...

  10. 第五部分shell项目一监控脚本

    需求: 使用shell定制各种个性化告警工具,但需要统一化管理.规范化管理. 思路:指定一个脚本包,包含主程序.子程序.配置文件.邮件引擎.输出日志等.主程序:作为整个脚本的入口,是整个系统的命脉.配 ...