zoukankan      html  css  js  c++  java
  • POJ1743---Musical Theme (后缀数组+二分)

    题意 :求最长不相交重复子串的长度。。

    可以先求出LCP,,对于长度 二分出答案。。(竟然不会写二分)

      1 #include <set>
      2 #include <map>
      3 #include <cmath>
      4 #include <ctime>
      5 #include <queue>
      6 #include <stack>
      7 #include <cstdio>
      8 #include <string>
      9 #include <vector>
     10 #include <cstdlib>
     11 #include <cstring>
     12 #include <iostream>
     13 #include <algorithm>
     14 using namespace std;
     15 typedef unsigned long long ull;
     16 typedef long long ll;
     17 const int inf = 0x3f3f3f3f;
     18 const double eps = 1e-8;
     19 const int maxn = 2e4+10;
     20 int sa[maxn], k, len, tmp[maxn], rank[maxn];
     21 int s[maxn];
     22 bool cmp(int i, int j)
     23 {
     24     if (rank[i] != rank[j])
     25         return rank[i] < rank[j];
     26     else
     27     {
     28         int x = (i + k <= len ? rank[i+k] : -1);
     29         int y = (j + k <= len ? rank[j+k] : -1);
     30         return x < y;
     31     }
     32 }
     33 void build_sa()
     34 {
     35     for (int i = 0; i <= len; i++)
     36     {
     37         sa[i] = i;
     38         rank[i] = i < len ? s[i] : -1;
     39     }
     40     for (k = 1; k <= len; k *= 2)
     41     {
     42         sort (sa, sa+len+1, cmp);
     43         tmp[sa[0]] = 0;
     44         for (int i = 1; i <=  len; i++)
     45         {
     46             tmp[sa[i]] = tmp[sa[i-1]] + (cmp(sa[i-1], sa[i]) ? 1 : 0);
     47         }
     48         for (int i = 0; i <= len; i++)
     49         {
     50             rank[i] = tmp[i];
     51         }
     52     }
     53 }
     54 int lcp[maxn];
     55 void Get_lcp()
     56 {
     57     for (int i = 0; i < len; i++)
     58     {
     59         rank[sa[i]] = i;
     60     }
     61     int h = 0;
     62     lcp[0] = 0;
     63     for (int i = 0; i < len; i++)
     64     {
     65         int j = sa[rank[i]-1];
     66         if (h > 0)
     67             h--;
     68         for (; i+h < len && j+h < len; h++)
     69             if (s[i+h] != s[j+h])
     70                 break;
     71         lcp[rank[i]] = h;
     72     }
     73 }
     74 bool check(int m)
     75 {
     76     int mini = len, maxi = 0;
     77     for (int i = 1; i <= len; i++)
     78     {
     79         if (maxi - mini >= m )
     80             return true;
     81         if (lcp[i] < m)
     82         {
     83             mini = len, maxi = 0;
     84             continue;
     85         }
     86         mini = min(sa[i-1], mini);
     87         maxi = max(sa[i-1], maxi);
     88         mini = min(sa[i], mini);
     89         maxi = max(sa[i], maxi);
     90     }
     91     return false;
     92 }
     93 int main()
     94 {
     95     #ifndef ONLINE_JUDGE
     96         freopen("in.txt","r",stdin);
     97     #endif
     98     int n;
     99     while (scanf ("%d", &n), n)
    100     {
    101         for (int i = 0; i < n; i++)
    102             scanf ("%d", s+i);
    103         for (int i = 0; i < n-1; i++)
    104             s[i] = s[i+1] - s[i] + 89;
    105         len = n-1;
    106         build_sa();
    107         Get_lcp();
    108         int ua = 0, ub = len;
    109         int mid;
    110         while (ua+1 < ub)
    111         {
    112             mid = (ua + ub ) >> 1;
    113             if (check(mid) == true)
    114                 ua = mid;
    115             else
    116                 ub = mid;
    117         }
    118         ua = (ua < 4 ? 0 : ua + 1);
    119         printf("%d
    ", ua);
    120     }
    121     return 0;
    122 }
  • 相关阅读:
    02-线性结构1 两个有序链表序列的合并
    ScSPM
    中国大学MOOC-陈越、何钦铭-数据结构-笔记
    01-复杂度1 最大子列和问题(剑指offer和PAT)
    Matlab中配置VLFeat
    循环队列实现
    对于利用pca 和 cca 进行fmri激活区识别的理解
    对于利用ica进行fmri激活区识别的理解
    利用spm提供的MoAEpilot听觉数据学习预处理以及单被试glm分析与统计推断
    fsl的feat软件分包使用笔记
  • 原文地址:https://www.cnblogs.com/oneshot/p/4342816.html
Copyright © 2011-2022 走看看