• POJ3261Milk Patterns后缀数组


    第一道后缀数组的题目,求得height之后,二分答案就可以,后缀数组的数组绕来绕去,实在感觉有点乱七八糟啊,整体复杂度为nlogn,包过

    View Code
      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 using namespace std;
      5 #define N 20005
      6 #define M 100005
      7 #define max(a,b) ((a)>(b)?(a):(b))
      8 int s[N];
      9 int sa[N],rank[N],height[N];
     10 int t[N],t2[N],c[M],n,ti;
     11 void build_sa(int m)
     12 {
     13     int i,k,*x = t, *y = t2;
     14     memset(c,0,sizeof(c));
     15     for(i = 0;i < n; i++)
     16     {
     17         c[x[i] = s[i]]++;
     18     }
     19     for(i = 1;i < m; i++)
     20     {
     21         c[i] += c[i-1];
     22     }
     23     for(i = n - 1; i >= 0; i--)
     24         sa[--c[x[i]]] = i;
     25     for(k = 1; k <= n ; k <<= 1)
     26     {
     27         int p = 0;
     28         for(i = n - k; i < n; i++)
     29             y[p++] = i;
     30         for(i = 0; i < n; i++)
     31             if(sa[i] >= k)
     32                 y[p++] = sa[i] - k;
     33         memset(c,0,sizeof(c));
     34         for(i = 0; i < n; i++)
     35             c[x[y[i]]]++;
     36         for(i = 1; i < m; i++)
     37             c[i] += c[i-1];
     38         for(i = n - 1; i >= 0; i--)
     39             sa[--c[x[y[i]]]] = y[i];
     40         swap(x,y);
     41         p = 1;
     42         x[sa[0]] = 0;
     43         for(i = 1; i < n; i++)
     44             x[sa[i]] = ((y[sa[i - 1]] == y[sa[i]]) && (y[sa[i - 1] + k] == y[sa[i] + k]))?p - 1:p++;
     45         if(p >= n)
     46             break;
     47         m = p;
     48     }
     49 }
     50 void geth()
     51 {
     52     int i,j,k = 0;
     53     for(i = 0; i < n; i++)
     54         rank[sa[i]] = i;
     55     for(i = 0; i < n; i++)
     56     {
     57         if(k)
     58             k--;
     59         j = sa[rank[i] - 1];
     60         while(s[i+k] == s[j+k])
     61             k++;
     62         height[rank[i]] = k;
     63     }
     64 }
     65 bool check(int len)
     66 {
     67     int i;
     68     int sum;
     69     sum = 0;
     70     for(i = 0; i < n; i++)
     71     {
     72         if(height[i] >= len)
     73         {
     74             sum++;
     75             if(sum == ti - 1)
     76                 return true;
     77         }
     78         else
     79         {
     80             sum = 0;
     81         }
     82     }
     83     return false;
     84 }
     85 int main()
     86 {
     87     int i,j;
     88     int m;
     89     int l,r,mid;
     90     while(scanf("%d%d",&n,&ti) != EOF)
     91     {
     92         m = 0;
     93         for(i = 0; i < n; i++)
     94         {
     95             scanf("%d",&s[i]);
     96             m = max(m,s[i]);
     97         }
     98         m++;
     99         build_sa(m);
    100         geth();
    101         l = 0;
    102         r = n;
    103         while(l <= r)
    104         {
    105             mid = (l + r) >>1;
    106             if(check(mid))
    107                 l = mid + 1;
    108             else
    109                 r = mid - 1;
    110         }
    111         printf("%d\n",r);
    112     }
    113     return 0;
    114 }
  • 相关阅读:
    jquery select操作和联动操作
    chrome 31删除输入框的历史记录
    14、python开发之路-并发编程之I/O模型
    13、python开发之路-并发编程之多线程
    12、python全栈之路-并发编程之多进程
    11、python全栈之路-网络编程
    10、python全栈之路-面向对象进阶
    9、python全栈之路-模块与包
    8、python全栈之路-初识面向对象
    6、python全栈之路-常用模块
  • 原文地址:https://www.cnblogs.com/caozhenhai/p/2969218.html
Copyright © 2020-2023  润新知