zoukankan      html  css  js  c++  java
  • SPOJ

    题意

    给若干个串,求这些串最长公共子串的长度。

    传送门

    思路

    后缀自动机求lcs模版题。

    Code

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int maxn = 2e5+10;
    
    struct Pam {
        int len[maxn], link[maxn];
        int nxt[maxn][26];
        int last, tot;
        int mx[maxn], mi[maxn];
    
        void init() {
            len[0] = link[0] = 0;
            last = tot = 1;
        }
    
        void extend(int c) {
            c -= 'a';
            int cur = ++tot, p = last;
            len[cur] = len[last] + 1;
            for (; p && !nxt[p][c]; p = link[p]) nxt[p][c] = cur;
            if(!p) {
                link[cur] = 1;
            } else {
                int q = nxt[p][c];
                if(len[q] == len[p]+1) {
                    link[cur] = q;
                } else {
                    int clone = ++tot;
                    len[clone] = len[p] + 1;
                    memcpy(nxt[clone], nxt[q], sizeof(nxt[q]));
                    link[clone] = link[q];
                    for (; p && nxt[p][c] == q; p = link[p]) nxt[p][c] = clone;
                    link[q] = link[cur] = clone;
                }
            }
            last = cur;
        }
    
        int c[maxn], a[maxn];
    
        void topo(int n) {
            for (int i = 1; i <= tot; ++i) c[i] = 0;
            for (int i = 1; i <= tot; ++i) ++c[len[i]];
            for (int i = 1; i <= tot; ++i) c[i] += c[i-1];
            for (int i = 1; i <= tot; ++i) a[c[len[i]]--] = i;
            for (int i = 1; i <= tot; ++i) mi[i] = len[i];
        }
    
        void solve(const string &s) {
            int p = 1, cnt = 0, ans = 0;
            for (int i = 1; i <= tot; ++i) mx[i] = 0;
            for (int i = 0; s[i]; ++i) {
                int c = s[i] - 'a';
                if(nxt[p][c]) {
                    ++cnt;
                    p = nxt[p][c];
                } else {
                    for (; p && !nxt[p][c]; p = link[p]);
                    if(!p) cnt = 0, p = 1;
                    else cnt = len[p]+1, p = nxt[p][c];
                }
                mx[p] = max(mx[p], cnt);
            }
            for (int i = tot; i >= 1; --i) mx[link[a[i]]] = max(mx[link[a[i]]], mx[a[i]]);
            for (int i = 1; i <= tot; ++i) mi[i] = min(mi[i], mx[i]);
        }
    
        void write() {
            int ans = 0;
            for (int i = 1; i <= tot; ++i) ans = max(ans, mi[i]);
            printf("%d
    ", ans);
        }
    }sam;
    string str;
    
    int main() {
    //    freopen("input.in", "r", stdin);
        sam.init();
        cin >> str;
        int n = str.length();
        for (int i = 0; str[i]; ++i) sam.extend(str[i]);
        sam.topo(n);
        while(cin >> str)
            sam.solve(str);
        sam.write();
        return 0;
    }
    
  • 相关阅读:
    Eclipse(MyEclipse)使用技巧——改动凝视字体大小
    C++标准库之 Lower_Bound, upper_Bound
    Mongodb地理空间索引
    AfxMessageBox和MessageBox差别
    具体解释VB中连接access数据库的几种方法
    C++中this指针的使用方法.
    秒杀多线程第四篇 一个经典的多线程同步问题
    设计模式学习03—抽象工厂模式
    Neutron中的Service类
    Opencv学习笔记(六)SURF学习笔记
  • 原文地址:https://www.cnblogs.com/acerkoo/p/11706210.html
Copyright © 2011-2022 走看看