码迷,mamicode.com
首页 > 编程语言 > 详细

算法学习:回文自动机

时间:2019-08-09 17:50:15      阅读:99      评论:0      收藏:0      [点我收藏+]

标签:fail   onclick   manacher   class   isp   解决   const   long   names   

【定义】

【自动机】

参照AC自动机

 


【前置知识】

【AC自动机】

【manacher】

其实不学这两个也可以,但是学过之后会更方便理解

 


【解决问题】

主要解决回文串的问题

能求出   字符串中回文子串的长度和出现次数

 


 

 

 

 

技术图片
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#define ll long long
using namespace std;
const int mod = 19930726;
const int MAXN = 1000010;
ll k;
int n, cnt;
int now;
struct note
{
    int son[26];
    ll len;
    int  siz;
}trie[MAXN];
int fail[MAXN], pos;
bool operator<(note a, note b)
{
    return a.len > b.len;
}
char s[MAXN];
int get(int x)
{
    while (s[pos] != s[pos - trie[x].len - 1]) x = fail[x];
    return x;
}
void insert(int x)
{
    int cur = get(now);
    if (!trie[cur].son[x])
    {
        int u = ++cnt;
        trie[u].len = trie[cur].len + 2;
        fail[u] = trie[get(fail[cur])].son[x];
        trie[cur].son[x] = u;
    }
    trie[trie[cur].son[x]].siz++;
    now = trie[cur].son[x];
}
ll poww(ll a, int b)
{
    ll res = 1;
    while (b)
    {
        if (b & 1)
        {
            res = (res*a) % mod;
        }
        a = (a*a) % mod;
        b = b >> 1;
    }
    return res;
}
void init()
{
    fail[0] = 1; fail[1] = 0;
    now = 0, cnt = 1;
    trie[1].len = -1;
}
int main()
{
    scanf("%d%lld", &n, &k);
    scanf("%s", s+1);
    init();
    s[0] = 0;
    for (pos = 1; pos <= n; pos++)
        insert(s[pos] - a);

    for (int i = cnt; i >= 2; i--)
        trie[fail[i]].siz = (trie[fail[i]].siz + trie[i].siz) % mod;
    //for (int i = 1; i <= cnt; i++)
        //printf("%lld %d\n", trie[i].len, trie[i].siz);
    sort(trie + 1, trie + 1 + cnt);
    ll ans = 1;
    int pos = 1;
    while (k)
    {
        if (pos > cnt)
        {
            printf("-1");
            return 0;
        }
        if (trie[pos].len % 2 == 0)
        {
            pos++;
            continue;
        }
        ans = (ans*poww(trie[pos].len, k < trie[pos].siz ? k : trie[pos].siz)) % mod;
        k -= k < trie[pos].siz ? k : trie[pos].siz;
        pos++;
    }
    printf("%lld", ans);
    return 0;
}
View Code

 

算法学习:回文自动机

标签:fail   onclick   manacher   class   isp   解决   const   long   names   

原文地址:https://www.cnblogs.com/rentu/p/11305837.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!