zoukankan      html  css  js  c++  java
  • 【BZOJ4480】 [JSOI2013] 快乐的jyy(回文自动机裸题)

    点此看题面

    大致题意: 给定两个字符串,问有多少对子串满足二者是相同的回文串。

    回文自动机

    感觉是一道比较裸的题目。

    直接建出两个串的回文自动机,然后倒序枚举节点,统计(C)(子树大小)的同时求出(sum C[0] imes C[1])即为答案

    代码

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 50000
    using namespace std;
    int n;char s[N+5];
    class PalindromeAutomation//回文自动机
    {
    	private:
    		int Nt,lst;struct node {int L,C[2],F,S[30];}O[2*N+5];
    		I int Fail(RI x,CI id) {W(s[id-O[x].L-1]^s[id]) x=O[x].F;return x;}
    	public:
    		I PalindromeAutomation() {O[O[0].F=Nt=1].L=-1;}I void Init() {lst=0;}
    		I void Ins(CI id,CI op)//插入元素
    		{
    			RI x=s[id]&31,t=Fail(lst,id),o;!O[t].S[x]&&(o=++Nt,
    				O[o].L=O[t].L+2,O[o].F=O[Fail(O[t].F,id)].S[x],O[t].S[x]=o);
    			++O[lst=O[t].S[x]].C[op];//C统计出现次数
    		}
    		I void Work()//求答案
    		{
    			RI i;long long t=0;for(i=Nt;i^1;--i)//倒序枚举
    				t+=1LL*O[i].C[0]*O[i].C[1],O[O[i].F].C[0]+=O[i].C[0],O[O[i].F].C[1]+=O[i].C[1];//统计答案,上传信息
    			printf("%lld
    ",t);
    		}
    }P;
    int main()
    {
    	RI i;for(scanf("%s",s+1),n=strlen(s+1),P.Init(),i=1;i<=n;++i) P.Ins(i,0);
    	for(scanf("%s",s+1),n=strlen(s+1),P.Init(),i=1;i<=n;++i) P.Ins(i,1);return P.Work(),0;
    }
    
  • 相关阅读:
    SSL 1010——方格取数
    SSL 1558——科技庄园
    SSL 2295——暗黑破坏神
    SSL 2294——打包
    SSL 2293——暗黑游戏
    SSL 2305——竞赛总分
    SSL 1072——砝码称重
    SSL 2291——分组背包
    SSL 2290——潜水员
    SSL 2301——混合背包
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ4480.html
Copyright © 2011-2022 走看看