zoukankan      html  css  js  c++  java
  • poj 3261 Milk Patterns 后缀数组+二分

      1 /***********************************************************
      2 题目:      Milk Patterns(poj 3261)
      3 链接:      http://poj.org/problem?id=3261
      4 题意:      给一串数字,求这些数字中公共子串个数大于k的
      5             最长串。
      6 算法:      后缀数组+二分
      7 ***********************************************************/
      8 #include<iostream>
      9 #include<cstdio>
     10 #include<cstring>
     11 #include<algorithm>
     12 using namespace std;
     13 
     14 const int mx=20010;
     15 int s[mx],sa[mx],t[mx],t2[mx],c[mx*50],n,k;
     16 int rank[mx],height[mx];
     17 
     18 void build_sa(int m)
     19 {
     20     int i,*x=t,*y=t2;
     21     for (i=0;i<m;i++) c[i]=0;
     22     for (i=0;i<n;i++) c[x[i]=s[i]]++;
     23     for (i=1;i<m;i++) c[i]+=c[i-1];
     24     for (i=n-1;i>=0;i--) sa[--c[x[i]]]=i;
     25     for (int k=1;k<=n;k<<=1)
     26     {
     27         int p=0;
     28         for (i=n-k;i<n;i++) y[p++]=i;
     29         for (i=0;i<n;i++) if (sa[i]>=k) y[p++]=sa[i]-k;
     30         for (i=0;i<m;i++) c[i]=0;
     31         for (i=0;i<n;i++) c[x[y[i]]]++;
     32         for (i=1;i<m;i++) c[i]+=c[i-1];
     33         for (i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];
     34         swap(x,y);
     35         p=1;
     36         x[sa[0]]=0;
     37         for (i=1;i<n;i++)
     38         x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
     39         if (p>=n) break;
     40         m=p;
     41     }
     42 }
     43 
     44 void getHeight()
     45 {
     46     int i,j,k=0;
     47     for (i=0;i<n;i++) rank[sa[i]]=i;
     48     for (i=0;i<n-1;i++)
     49     {
     50         if (k) k--;
     51         int j=sa[rank[i]-1];
     52         while (s[i+k]==s[j+k])
     53         {
     54             k++;
     55         }
     56         height[rank[i]]=k;
     57 
     58     }
     59 }
     60 
     61 bool check(int len)
     62 {
     63     int i=0;
     64     while (i<n)
     65     {
     66         while (i<n&&height[i]<len) i++;
     67         if (i>=n) return false;
     68         int cut=1;
     69         while (height[i]>=len)
     70         {
     71             cut++;
     72             i++;
     73         }
     74         if (cut>=k) return true;
     75     }
     76     return false;
     77 }
     78 
     79 int getans()
     80 {
     81     int l=1,r=n-1;
     82     int ans=1;
     83     while (l<=r)
     84     {
     85         int m=(l+r)/2;
     86         if (check(m))
     87         {
     88             l=m+1;
     89             ans=m;
     90         }
     91         else r=m-1;
     92     }
     93     return ans;
     94 }
     95 
     96 int main()
     97 {
     98     scanf("%d%d",&n,&k);
     99     for (int i=0;i<n;i++)
    100     {
    101         scanf("%d",&s[i]);
    102     }
    103     s[n]=0;
    104     n++;
    105     build_sa(1000001);
    106     getHeight();
    107     int ans=getans();
    108     printf("%d
    ",ans);
    109 }
  • 相关阅读:
    IDETalk
    servlet概述
    过滤器(Filter)
    ieda常用快捷键
    UUID
    JRebel 7.0.10 for intellij IDEA 2017.1
    BP神经网络(手写数字识别)
    遗传算法解决TSP问题
    [CODEVS1258]关路灯
    [NOIP2007]统计数字
  • 原文地址:https://www.cnblogs.com/pblr/p/5686079.html
Copyright © 2011-2022 走看看