HDOJ 3948 The Number of Palindromes 回文串自动机

看上去像是回文串自动机的模板题,就来了一发

The Number of Palindromes

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)

Total Submission(s): 1992    Accepted Submission(s): 694

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

2011 Multi-University Training
Contest 11 - Host by UESTC

/* ***********************************************
Author        :CKboss
Created Time  :2015年04月17日 星期五 09时38分22秒
File Name     :pt.cpp
************************************************ */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>

using namespace std;

const int C=30;
const int maxn=120000;

struct Node
{
	Node *ch[C],*suffix;
	int len;
}bar[maxn],*foo,*last,*odd,*even;

char s[maxn];
int n,cnt;
// cnt=foo-bar=count of palindromes , n the number of char added

void init()
{
	odd=bar; even=last=odd+1; foo=even+1;
	memset(odd->ch,0,sizeof(odd->ch));
	memset(even->ch,0,sizeof(even->ch));
	odd->suffix=even->suffix=odd;
	odd->len=-1; even->len=0;
	n=0; cnt=0;
}

Node* New_Node(int x)
{
	memset(foo->ch,0,sizeof(foo->ch));
	foo->len=x;
	return foo++;
}

int index(char x) { return x-'a'; }

Node* get(Node*p)
{
	while(n-p->len-2<0||s[n-p->len-2]!=s[n-1])
		p=p->suffix;
	return p;
}

bool add(char c)
{
	int x=index(c); s[n++]=c;
	Node* p =get(last);
	if(!p->ch[x])
	{
		last = New_Node(p->len+2);
		if(last->len==1) last->suffix=even;
		else last->suffix=get(p->suffix)->ch[x];
		/// guarantee proper suffix
		p->ch[x]=last; cnt++;
		return true;
	}
	else
	{
		last=p->ch[x];
		return false;
	}
}

char str[maxn];

int main()
{
	int T_T,cas=1;
	scanf("%d",&T_T);
	while(T_T--)
	{
		scanf("%s",str);
		int len=strlen(str);
		init();
		for(int i=0;i<len;i++)
		{
			add(str[i]);
		}
		printf("Case #%d: %d\n",cas++,cnt);
	}
}
时间: 2024-10-20 08:54:11

HDOJ 3948 The Number of Palindromes 回文串自动机的相关文章

BZOJ 3676: [Apio2014]回文串 回文串自动机

裸的回文串自动机 3676: [Apio2014]回文串 Time Limit: 20 Sec  Memory Limit: 128 MB Submit: 504  Solved: 152 [Submit][Status][Discuss] Description 考虑一个只包含小写拉丁字母的字符串s.我们定义s的一个子串t的"出 现值"为t在s中的出现次数乘以t的长度.请你求出s的所有回文子串中的最 大出现值. Input 输入只有一行,为一个只包含小写字母(a -z)的非空字符串s

HDOJ 3948 The Number of Palindromes 后缀数组

后缀数组求有多少个不同的回文串 The Number of Palindromes Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 1976    Accepted Submission(s): 690 Problem Description Now, you are given a string S. We want to kno

SP7586 NUMOFPAL - Number of Palindromes(回文树)

题意翻译 求一个串中包含几个回文串 题目描述 Each palindrome can be always created from the other palindromes, if a single character is also a palindrome. For example, the string "malayalam" can be created by some ways: malayalam = m + ala + y + ala + m malayalam = m

[bzoj 3676][uoj #103]【APIO2014】Palindromes回文串 后缀数组+manachar

给你一个由小写拉丁字母组成的字符串 ss.我们定义 ss 的一个子串的存在值为这个子串在 ss 中出现的次数乘以这个子串的长度. 对于给你的这个字符串 ss,求所有回文子串中的最大存在值. 输入格式 一行,一个由小写拉丁字母(a~z)组成的非空字符串 ss. 输出格式 输出一个整数,表示所有回文子串中的最大存在值. 样例一 input abacaba output 7 explanation 用 ∣s∣∣s∣ 表示字符串 ss 的长度. 一个字符串 s1s2-s∣s∣s1s2-s∣s∣ 的子串是

[APIO2014] [Uoj103] [Bzoj3676] Palindromes回文串 [Manacher,后缀数组]

用Manacher算法枚举回文子串,每次在后缀数组排序后的后缀数组中二分,因为用某一后缀和其他子串分别求匹配的长度,匹配长度在排序后该后缀的两侧具有单调性(匹配长度为min{H[x]|i<=x<=j},所以对于查询min(H[x])用ST表O(n)预处理,O(1)查询即可.Manacher时间复杂度O(n),后缀数组复杂度O(nlogn),总复杂度O(nlogn).注意二分时的边界条件! #include <iostream> #include <cstdio> #in

HDOJ/HDU 2163 Palindromes(判断回文串~)

Problem Description Write a program to determine whether a word is a palindrome. A palindrome is a sequence of characters that is identical to the string when the characters are placed in reverse order. For example, the following strings are palindro

hdu 3948 The Number of Palindromes

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 substri

Hdu 5340 Three Palindromes 最大回文串 Manacher

Three Palindromes Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 80    Accepted Submission(s): 21 Problem Description Can we divided a given string S into three nonempty palindromes? Input Fir

HDU 5340——Three Palindromes——————【manacher处理回文串】

Three Palindromes Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1244    Accepted Submission(s): 415 Problem Description Can we divided a given string S into three nonempty palindromes? Input F