zoukankan      html  css  js  c++  java
  • HDU 5157 Harry and magic string(回文树)

    Harry and magic string

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 223    Accepted Submission(s): 110


    Problem Description
    Harry got a string T, he wanted to know the number of T’s disjoint palindrome substring pairs. A string is considered to be palindrome if and only if it reads the same backward or forward. For two substrings of T:x=T[a1b1],y=T[a2b2](where a1 is the beginning index of x,b1 is the ending index of x. a2,b2 as the same of y), if both x and y are palindromes and b1<a2 or b2<a1 then we consider (x, y) to be a disjoint palindrome substring pair of T.
     

    Input
    There are several cases.
    For each test case, there is a string T in the first line, which is composed by lowercase characters. The length of T is in the range of [1,100000].
     

    Output
    For each test case, output one number in a line, indecates the answer.
     

    Sample Input
    aca aaaa
     

    Sample Output
    3 15
    求一个字符串中所有不相交的回文串对
    回文树,先倒着扫一遍,再正着扫一遍
    #include <iostream>
    #include <string.h>
    #include <stdlib.h>
    #include <algorithm>
    #include <math.h>
    #include <stdio.h>
    
    using namespace std;
    typedef long long int LL;
    const int MAX=1e5+5;
    char str[MAX];
    struct Tree
    {
    	int next[MAX][26];
    	int fail[MAX];
    	LL num[MAX];
    	int len[MAX];
    	int s[MAX];
    	int last;
    	int n;
    	int p;
    	int new_node(int x)
    	{
    		memset(next[p],0,sizeof(next[p]));
    		num[p]=0;
    		len[p]=x;
    		return p++;
    	}
    	void init()
    	{
    		p=0;
    		new_node(0);
    		new_node(-1);
    		last=0;
    		n=0;
    		s[0]=-1;
    		fail[0]=1;
    	}
    	int get_fail(int x)
    	{
    		while(s[n-len[x]-1]!=s[n])
    			x=fail[x];
    		return x;
    	}
    	LL add(int x)
    	{
    		x-='a';
    		s[++n]=x;
    		int cur=get_fail(last);
    		if(!(last=next[cur][x]))
    		{
    			int now=new_node(len[cur]+2);
    			fail[now]=next[get_fail(fail[cur])][x];
    			next[cur][x]=now;
    			num[now]=num[fail[now]]+1;
    			last=now;
    		}
    		return num[last];
    	}
    }tree;
    LL sum[MAX];
    int main()
    {
        while(scanf("%s",str)!=EOF)
    	{
    		int len=strlen(str);
    		sum[len]=0;
    		tree.init();
    		for(int i=len-1;i>=0;i--)
    		{
               sum[i]=sum[i+1]+tree.add(str[i]);
    		}
    		tree.init();
    		LL ans=0;
    		for(int i=0;i<len;i++)
    		{
                ans+=(LL)tree.add(str[i])*sum[i+1];
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    


  • 相关阅读:
    Centos7安装docker-ce
    postgresql-11主从复制(流复制)部署
    centos7安装postgreSql11
    CentOS7下安装PostgreSQL12
    postgres生成uuid
    软工第一次团队展示
    软工第一次结对编程作业
    软工第一次个人编程作业
    课程总结
    团队作业
  • 原文地址:https://www.cnblogs.com/dacc123/p/8228632.html
Copyright © 2011-2022 走看看