zoukankan      html  css  js  c++  java
  • 模板

    构造一种fail向同一个节点的回文机:
    abadabacaba
    这样caba和daba都会指向ba。

    带展示功能的回文自动机:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    struct Node {
        int len, ch[26], fail;
        int cnt;
        string str;
        Node(int len = 0) : len(len), fail(0) {
            memset(ch, 0, sizeof(ch));
            //下面是维护额外信息
            cnt = 0;
            str="";
        }
        void show() {
            printf("  str="%s"
    ", str.c_str());
            printf("  len=%d cnt=%d
    ",len,cnt);
        }
    };
    
    const int MAXN = 600000;
    
    //PalindromicAutomaton
    struct PAM {
        Node nd[MAXN + 5];
    
        int len, top, last;     // len为字符串长度,top为节点个数,last为最后插入字符所对应的节点
        char s[MAXN + 5];
        string ls;  //用来展示的辅助字符串
    
        int getfail(int x) {        //沿着fail指针找到第一个回文后缀
            while(s[len - nd[x].len - 1] != s[len])
                x = nd[x].fail;
            return x;
        }
    
        void init() {
            len = 0, top = 0, last = 0;
            nd[top] = Node(0);
            nd[top].fail = 1;
            nd[++top] = Node(-1);
            nd[top].fail = 0;
            s[0] = '$';
        }
    
        void extend(char c) {
            s[++len] = c;
            int now = getfail(last);     //找到插入的位置
            ls = nd[now].str + c;   //用来展示的辅助字符串
            if(!nd[now].ch[c - 'a']) {     //若没有这个节点,则新建并求出它的fail指针
                nd[++top] = Node(nd[now].len + 2);
                nd[top].fail = nd[getfail(nd[now].fail)].ch[c - 'a'];
                nd[now].ch[c - 'a'] = top;
            }
            last = nd[now].ch[c - 'a'];
            nd[last].str = ls;  //用来展示的辅助字符串
            //下面是维护额外信息
            ++nd[last].cnt;
        }
    
        void show() {
            for(int i = top; i >= 0; --i) {
                printf("node:  id=%d
    ", i);
                nd[i].show();
                printf("fail:  id=%d
    ", nd[i].fail);
                nd[nd[i].fail].show();
                puts("");
            }
        }
    } pam;
    
    char s[MAXN + 5];
    ll ans[MAXN + 5];
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in", "r", stdin);
    #endif // Yinku
        while(~scanf("%s", s)) {
            int n = strlen(s);
            pam.init();
            for(int i = 0; s[i] != ''; ++i)
                pam.extend(s[i]);
            //pam.show();
            for(int i = pam.top; i >= 2; --i) {
                Node *now = &pam.nd[i];
                Node *fail = &pam.nd[now->fail];
                fail->cnt += now->cnt;
            }
            pam.show();
        }
        return 0;
    }
    
  • 相关阅读:
    JNI 反射
    JNI 动态注册
    Nt* 与 Zw* 区别
    python之线程
    爬虫框架之Scrapy(四 ImagePipeline)
    初试PySnooper
    爬虫框架之Scrapy(三 CrawlSpider)
    爬虫框架之Scrapy(二)
    爬虫框架之Scrapy(一)
    selenium+谷歌无头浏览器爬取网易新闻国内板块
  • 原文地址:https://www.cnblogs.com/Yinku/p/11243179.html
Copyright © 2011-2022 走看看