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());
    	}
    }
    
    
  • 相关阅读:
    【项目 · Wonderland】UML设计
    【项目 · Wonderland】预则立 && 他山之石
    【项目 · Wonderland】需求规格说明书 · 终版
    【项目 · 学生部门互选系统】项目展示
    【项目 · Wonderland】立项报告
    React 封装Form表单组件
    前端算法题解析 《四》
    前端算法题解析 《三》
    前端算法题解析 《二》
    前端算法题解析 《一》
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9102163.html
Copyright © 2011-2022 走看看