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 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月05日 星期日 14时46分57秒
File Name     :HDOJ3948.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 maxn = 220000;

int sa[maxn],rank[maxn],rank2[maxn],h[maxn];
int c[maxn],*x,*y,ans[maxn];
char str[maxn];

void init()
{
	memset(sa,0,sizeof(sa));
	memset(str,0,sizeof(str));
	memset(rank,0,sizeof(rank));
}

bool cmp(int* r,int a,int b,int l,int n)
{
	if(r[a]==r[b]&&a+l<n&&b+l<n&&r[a+l]==r[b+l]) return true;
	return false;
}

void radix_sort(int n,int sz)
{
	for(int i=0;i<sz;i++) c[i]=0;
	for(int i=0;i<n;i++) c[x[y[i]]]++;
	for(int i=1;i<sz;i++) c[i]+=c[i-1];
	for(int i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];
}

void get_sa(char c[],int n,int sz=128)
{
	x=rank,y=rank2;
	for(int i=0;i<n;i++) x[i]=c[i],y[i]=i;
	radix_sort(n,sz);
	for(int len=1;len<n;len=len*2)
	{
		int yid=0;
		for(int i=n-len;i<n;i++) y[yid++]=i;
		for(int i=0;i<n;i++) if(sa[i]>=len) y[yid++]=sa[i]-len;
		radix_sort(n,sz);
		swap(x,y);
		x[sa[0]]=yid=0;
		for(int i=1;i<n;i++)
			x[sa[i]]=cmp(y,sa[i],sa[i-1],len,n)?yid:++yid;
		sz=yid+1;
		if(sz>=n) break;
	}
	for(int i=0;i<n;i++) rank[i]=x[i];
}

void get_h(char str[],int n)
{
    int k=0; h[0]=0;
    for(int i=0;i<n;i++)
    {
        if(rank[i]==0) continue;
        k=max(k-1,0);
        int j=sa[rank[i]-1];
        while(i+k<n&&j+k<n&&str[i+k]==str[j+k]) k++;
        h[rank[i]]=k;
    }
}  

int dp[maxn][20],Log[maxn];

void RMQ_init(int n)
{
	memset(dp,63,sizeof(dp));
	for(int i=0;i<n;i++) dp[i][0]=h[i];
	for(int i=1;i<=Log[n];i++)
		for(int j=0;j+(1<<i)-1<n;j++)
			dp[j][i]=min(dp[j][i-1],dp[j+(1<<(i-1))][i-1]);
}

int lcp(int l,int r)
{
	l=rank[l],r=rank[r];
	if(l>r) swap(l,r);
	int a=l+1,b=r;
	int k=Log[b-a+1];
	return min(dp[a][k],dp[b-(1<<k)+1][k]);
}

void PRE()
{
	int m=strlen(str);
	for(int i=0;i<m;i++) str[i+m+1]=str[m-1-i];
	str[m]='$';
	str[2*m+1]=0;
}

int main()
{
    Log[0] = -1;
    for(int i=1;i<=maxn;i++)  Log[i]=(i&(i-1))?Log[i-1]:Log[i-1] + 1 ;  

	int T_T,cas=1;
	scanf("%d",&T_T);

    while(T_T--)
    {
		init();
		scanf("%s",str);

		PRE();
        int n=strlen(str);
        get_sa(str,n);
        get_h(str,n);
        RMQ_init(n);  

		/********* gao ************/
		int pre1=0,pre2=0,l,ans=0;
		for(int i=1;i<n;i++)
		{

			pre1=min(pre1,h[i]);
			l=lcp(sa[i],n-1-sa[i]);
			if(l>pre1)
			{
				ans+=l-pre1;
				pre1=l;
			}
			pre2=min(pre2,h[i]);
			l=lcp(sa[i],n-sa[i]);
			if(l>pre2)
			{
				ans+=l-pre2;
				pre2=l;
			}
		}
		printf("Case #%d: %d\n",cas++,ans);

    }
    return 0;
}
时间: 2024-08-08 17:53:53

HDOJ 3948 The Number of Palindromes 后缀数组的相关文章

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

【HDOJ】3948 The Number of Palindromes

后缀数组求不重复回文子串数目.注意dp数组. 1 /* 3948 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <

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

HDOJ 题目3518 Boring counting(后缀数组,求不重叠重复次数最少为2的子串种类数)

Boring counting Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2253    Accepted Submission(s): 924 Problem Description 035 now faced a tough problem,his english teacher gives him a string,whic

HDOJ 题目4691 Front compression(后缀数组+RMQ最长前缀)

Front compression Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others) Total Submission(s): 1652    Accepted Submission(s): 604 Problem Description Front compression is a type of delta encoding compression algorithm w

hdu 3948 后缀数组

The Number of Palindromes Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 2465    Accepted Submission(s): 841 Problem Description Now, you are given a string S. We want to know how many distin

HDOJ 4691 Front compression 后缀数组

后缀数组求两子串间的最大公共前缀. Front compression Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others) Total Submission(s): 1382    Accepted Submission(s): 517 Problem Description Front compression is a type of delta encoding compr

HDU - 3948 后缀数组+Manacher

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3948 题意:给定一个字符串,求字符串本质不同的回文子串个数. 思路:主要参考该篇解题报告 先按照manacher的构造方法改造一遍串,然后跑一遍manacher.求出以i为中心的最长回文串长度p[i]. 然后跑一遍后缀数组,若已经求得后缀sa[i-1]对答案的贡献,然后现在计算后缀sa[i],本来是要加上以sa[i]为中心的回文串的个数p[sa[i]]. 我们可以维护一个tmp,也就是上图中蓝色的框

HDOJ 题目4416 Good Article Good sentence(后缀数组求a串子串在b串中不出现的种类数)

-每周六晚的BestCoder(有米!) Good Article Good sentence Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2784    Accepted Submission(s): 785 Problem Description In middle school, teachers used to encour