zoukankan      html  css  js  c++  java
  • [HDU2328]Corporate Identity(后缀数组)

    传送门

    求 n 个串的字典序最小的最长公共子串。

    和 2 个串的处理方法差不多。

    把 n 个串拼接在一起,中间连上一个没有出现过的字符防止匹配过界。

    求出 height 数组后二分公共子串长度给后缀数组分组。

    然后 check,每一组中是否所有的字符串都包含。

    直接遍历 sa 数组,第一个满足的结果就是字典序最小的。

    ——代码

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #define N 900005
      5 #define M 4001
      6 
      7 int n, len, m, start;
      8 int buc[N], x[N], y[N], sa[N], rank[N], height[N], belong[N];
      9 char s[N], a[M];
     10 bool f[M];
     11 
     12 inline void build_sa()
     13 {
     14     int i, k, p;
     15     for(i = 0; i < m; i++) buc[i] = 0;
     16     for(i = 0; i < len; i++) buc[x[i] = s[i]]++;
     17     for(i = 1; i < m; i++) buc[i] += buc[i - 1];
     18     for(i = len - 1; i >= 0; i--) sa[--buc[x[i]]] = i;
     19     for(k = 1; k <= len; k <<= 1)
     20     {
     21         p = 0;
     22         for(i = len - 1; i >= len - k; i--) y[p++] = i;
     23         for(i = 0; i < len; i++) if(sa[i] >= k) y[p++] = sa[i] - k;
     24         for(i = 0; i < m; i++) buc[i] = 0;
     25         for(i = 0; i < len; i++) buc[x[y[i]]]++;
     26         for(i = 1; i < m; i++) buc[i] += buc[i - 1];
     27         for(i = len - 1; i >= 0; i--) sa[--buc[x[y[i]]]] = y[i];
     28         std::swap(x, y);
     29         p = 1, x[sa[0]] = 0;
     30         for(i = 1; i < len; i++)
     31             x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k] ? p - 1 : p++;
     32         if(p >= len) break;
     33         m = p;
     34     }
     35 }
     36 
     37 inline void build_height()
     38 {
     39     int i, j, k = 0;
     40     for(i = 0; i < len; i++) rank[sa[i]] = i;
     41     for(i = 0; i < len; i++)
     42     {
     43         if(!rank[i]) continue;
     44         if(k) k--;
     45         j = sa[rank[i] - 1];
     46         while(s[i + k] == s[j + k] && i + k < len && j + k < len) k++;
     47         height[rank[i]] = k;
     48     }
     49 }
     50 
     51 inline bool check(int k)
     52 {
     53     int i, cnt = 1;
     54     memset(f, 0, sizeof(f));
     55     f[belong[sa[0]]] = 1;
     56     for(i = 1; i < len; i++)
     57         if(height[i] >= k)
     58         {
     59             if(!f[belong[sa[i]]]) cnt++;
     60             f[belong[sa[i]]] = 1;
     61             if(cnt == n)
     62             {
     63                 start = sa[i];
     64                 return 1;
     65             }
     66         }
     67         else
     68         {
     69             memset(f, 0, sizeof(f));
     70             f[belong[sa[i]]] = 1;
     71             cnt = 1;
     72         }
     73     return 0;
     74 }
     75 
     76 int main()
     77 {
     78     int i, j, l, r, mid, leng;
     79     while(scanf("%d", &n) && n)
     80     {
     81         len = 0;
     82         m = 256;
     83         memset(belong, 0, sizeof(belong));
     84         for(i = 1; i <= n; i++)
     85         {
     86             scanf("%s", a);
     87             for(j = 0; a[j] ^ ''; j++) s[len++] = a[j];
     88             s[len++] = '#';
     89             belong[len] = 1;
     90         }
     91         len--;
     92         build_sa();
     93         build_height();
     94         for(i = 1; i < len; i++) belong[i] += belong[i - 1];
     95         l = 1, r = len, leng = 0, start = -1;
     96         while(l <= r)
     97         {
     98             mid = (l + r) >> 1;
     99             if(check(mid)) leng = mid, l = mid + 1;
    100             else r = mid - 1;
    101         }
    102         if(leng && start ^ -1)
    103         {
    104             for(i = start; i < start + leng; i++) putchar(s[i]);
    105             putchar('
    ');
    106         }
    107         else puts("IDENTITY LOST");
    108     }
    109     return 0;
    110 } 
    View Code
  • 相关阅读:
    [传智播客学习日记]写在培训即将过半之前
    [传智播客学习日记]SQL语句一例通之二——查询、存储过程
    [传智播客学习日记]分页查询的存储过程
    [传智播客学习日记]保持HTTP状态的方法
    [传智播客学习日记]正则提取网页信息并写入文件
    激情黄健翔
    maxthon 2 预览版的邀请
    Head first design patterns 读书笔记 – Strategy(策略模式)
    如何在ReadOnly的DataGrid中的让CheckBox列可点击
    每天如何自动编译项目并将之打包添加到VSS中
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6984603.html
Copyright © 2011-2022 走看看