zoukankan      html  css  js  c++  java
  • 【Aizu2292】Common Palindromes(回文树)

    【Aizu2292】Common Palindromes(回文树)

    题面

    Vjudge
    神TMD日语
    翻译:
    给定两个字符串(S,T),询问((i,j,k,l))这样的四元组个数
    满足(S[i,j],T[k,l])都是回文串并且(S[i,j]=T[k,l])

    题解

    自己(yy)一下就会做了
    回文树又叫做回文自动机,所以当然可以用来进行回文串的识别和匹配了
    对于一个串构建(PAM)或者说回文树,统计一下每个回文串的出现次数
    再用另外一个串在(PAM)上进行匹配,计算一下每个节点被访问的次数
    最后把每个节点的两个值乘起来求和就行了

    #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 55555
    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 PAM
    {
    	struct Node{int son[26],len,ff,v;}t[MAX];
    	int tot,last;
    	void init(){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;
    			while(s[n-t[k].len-1]!=s[n])k=t[k].ff;
    			t[v].len=t[p].len+2;
    			t[v].ff=t[k].son[c];
    			t[p].son[c]=v;
    		}
    		last=t[p].son[c];
    		t[last].v++;
    	}
    }P;
    int f[MAX];
    char ch[MAX];
    ll ans=0;
    int main()
    {
    	P.init();
    	scanf("%s",ch+1);
    	for(int i=1,l=strlen(ch+1);i<=l;++i)P.extend(ch[i]-65,i,ch);
    	scanf("%s",ch+1);
    	for(int i=1,l=strlen(ch+1),now=1;i<=l;++i)
    	{
    		int c=ch[i]-65;
    		while(now!=1&&(!P.t[now].son[c]||ch[i]!=ch[i-P.t[now].len-1]))now=P.t[now].ff;
    		if(P.t[now].son[c]&&ch[i]==ch[i-P.t[now].len-1]){now=P.t[now].son[c];f[now]++;}
    		else now=1;
    	}
    	for(int i=P.tot;i;--i)f[P.t[i].ff]+=f[i];
    	for(int i=P.tot;i;--i)P.t[P.t[i].ff].v+=P.t[i].v;
    	for(int i=1;i<=P.tot;++i)
    		ans+=1ll*f[i]*P.t[i].v;
    	printf("%lld
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    jQuery获取当前元素是该父元素的第几个元素&获取父元素的第n个子元素
    获取当前月份的天数
    获取当年的每个月份的天数:
    解决ul下的li换行问题,(父元素div加overflow:scroll没作用的问题)
     获取当年的月份的天数:
    程序员成长道路上必经的几个阶段
    CSS如何让文字垂直居中?
    2015年7个重要的Web设计趋势
    引入css文件时,css link和@import区别
    在html页面引用css文件的方法
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9152682.html
Copyright © 2011-2022 走看看