zoukankan      html  css  js  c++  java
  • 【CodeChef】Palindromeness(回文树)

    【CodeChef】Palindromeness(回文树)

    题面

    Vjudge
    CodeChef
    中文版题面

    题解

    构建回文树,现在的问题就是要求出当前回文串节点的长度的一半的那个回文串所代表的节点
    定义(half)表示长度最长并且长度小于等于当前节点长度一半的回文串所代表的节点
    (half)的求法,如果当前点的(len=1)(half)不存在
    否则,从构建回文树时的父亲节点(不是(fail)指针)所代表的那个点的(half)开始
    暴力跳(fail),直到找到满足条件的点,假设是(pos)
    那么,当前点的(half)就是(trans[pos][当前字符])
    完全不记得回文树怎么写了

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    #define MAX 111111
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    struct Node
    {
    	int len,ff;
    	int son[26];
    }t[MAX];
    struct PAM
    {
    	int last,tot;
    	ll cnt[MAX];
    	int val[MAX],half[MAX];
    	void init()
    	{
    		memset(t,0,sizeof(t));memset(cnt,0,sizeof(cnt));
    		t[tot=1].len=-1;t[0].ff=t[1].ff=1;
    	}
    	void extend(int c,int n,char *s)
    	{
    		int p=last;
    		while(s[n-t[p].len-1]!=s[n])p=t[p].ff;
    		if(!t[p].son[c])
    		{
    			int v=++tot,k=t[p].ff;
    			t[v].len=t[p].len+2;
    			while(s[n-t[k].len-1]!=s[n])k=t[k].ff;
    			t[v].ff=t[k].son[c];
    			t[p].son[c]=v;
    			if(t[v].len==1)half[v]=0;
    			else
    			{
    				int pos=half[p];
    				while(s[n-t[pos].len-1]!=s[n]||(2+t[pos].len)*2>t[v].len)pos=t[pos].ff;
    				half[v]=t[pos].son[c];
    			}
    			val[v]=1+(t[v].len/2==t[half[v]].len?val[half[v]]:0);
    		}
    		last=t[p].son[c];
    		cnt[last]++;
    	}
    	ll Calc()
    	{
    		ll ret=0;
    		for(int i=tot;i;--i)cnt[t[i].ff]+=cnt[i];
    		for(int i=tot;i;--i)ret+=cnt[i]*val[i];
    		return ret;
    	}
    }PT;
    char ch[MAX];
    int main()
    {
    	int T;scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%s",ch+1);
    		PT.init();
    		for(int i=1,l=strlen(ch+1);i<=l;++i)PT.extend(ch[i]-97,i,ch);
    		printf("%lld
    ",PT.Calc());
    	}
    }
    
    
  • 相关阅读:
    mapreduce 的过程
    bootstrap当中,实现一些常用的元素居中
    如何理解人工智能、机器学习和深度学习三者的关系
    MapReduce的局限性
    MapReduce的计算资源划分
    Java中的堆和栈的区别
    java面试01-网络知识
    01Java经典问题
    06数据库复习03
    05数据库复习02
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9102163.html
Copyright © 2011-2022 走看看