zoukankan      html  css  js  c++  java
  • [POI 2000] 公共串

    [题目链接]

            https://www.lydsy.com/JudgeOnline/problem.php?id=2946

    [算法]

             建立多串后缀树

             对于后缀树上的每个点 , 判断该节点所代表的等价类是否在所以字符串中出现 , 用该点的深度更新答案

             时间复杂度 : O(NL)

    [代码] 

           

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int N = 1e5 + 10;
    const int ALPHA = 26;
    
    int n , ans;
    char s[N];
    
    template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
    template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
    template <typename T> inline void read(T &x)
    {
        T f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    
    struct Suffix_Automaton
    {
            int sz , last;
            int father[N] , child[N][ALPHA] , depth[N];
            bool lab[N][6];
            vector< int > a[N];
            Suffix_Automaton()
            {
                    sz = 1;
                    last = 1;        
            }        
            inline int new_node(int dep)
            {
                    depth[++sz] = dep;
                    father[sz] = 0;
                    memset(child[sz] , 0 , sizeof(child[sz]));
                    memset(lab[sz] , 0 , sizeof(lab[sz]));
                    return sz;
            }
            inline void extend(int ch , int c)
          {
            int np = child[last][ch];
            if (np)
            {
                if (depth[np] == depth[last] + 1) 
                {
                    lab[np][c] = true;
                    last = np;
                } else
                {
                    int nq = new_node(depth[last] + 1);
                    father[nq] = father[np];
                    father[np] = nq;
                    memcpy(child[nq] , child[np] , sizeof(child[nq]));
                    for (int p = last; child[p][ch] == np; p = father[p]) 
                            child[p][ch] = nq;
                    lab[nq][c] = true;
                    last = nq;
                }
            } else
            {
                  int np = new_node(depth[last] + 1);
                  int p = last;
                  while (child[p][ch] == 0)
                  {
                      child[p][ch] = np;
                      p = father[p];
                  }
                  if (child[p][ch] == np)
                  {
                      father[np] = 1;
                      lab[np][c] = true;
                      last = np;
                      return;
                  }
                  int q = child[p][ch];
                  if (depth[q] == depth[p] + 1)
                  {
                      father[np] = q;
                      lab[np][c] = true;
                      last = np;
                      return; 
                  } else
                  {
                      int nq = new_node(depth[p] + 1);
                      father[nq] = father[q];
                      father[np] = father[q] = nq;
                      memcpy(child[nq] , child[q] , sizeof(child[q]));
                      while (child[p][ch] == q)
                      {
                          child[p][ch] = nq;
                          p = father[p];
                      }
                      lab[np][c] = true;
                      last = np;
                      return;
                  }
            }
             }
            inline void insert(char *s , int col)
            {
                    last = 1;
                    for (int i = 1; i <= strlen(s + 1); ++i)
                            extend(s[i] - 'a' , col);
            }
            inline void dfs(int u)
            {
                    for (unsigned i = 0; i < a[u].size(); ++i)
                    {
                            int v = a[u][i];
                            dfs(v);
                            for (int j = 1; j <= n; ++j)
                                    lab[u][j] |= lab[v][j];
                    }
                    bool all = true;
                    for (int i = 1; i <= n; ++i) all &= lab[u][i];
                    if (all) chkmax(ans , depth[u]);
            }
            inline void work()
            {
                    for (int i = 2; i <= sz; ++i)
                            a[father[i]].push_back(i);
                    dfs(1);
            }
    } SAM;
    
    int main()
    {
            
            read(n);
            for (int i = 1; i <= n; ++i)
            {
                    scanf("%s" , s + 1);
                    SAM.insert(s , i);
            }
            SAM.work();
            printf("%d
    " , ans);
            
            return 0;
        
    }
  • 相关阅读:
    "Key Violation" with ClientDataSet
    c# 的关键字 params,out,ref
    eval && JSON.parse
    json2.js
    C#中的索引器
    call , apply , caller , callee
    iphone&ipad图标去除高亮的光圈效果
    调用系统路线导航
    调科大讯飞出现的问题
    得到汉字首字母在表中的顺序位置
  • 原文地址:https://www.cnblogs.com/evenbao/p/10659940.html
Copyright © 2011-2022 走看看