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

    题目链接

    求可重叠k次的最长子串。

    二分子串长度x, 将height数组分组, 看是否有一组中的数量大于等于k。

      1 #include <iostream>
      2 #include <vector>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <algorithm>
      6 #include <cmath>
      7 #include <map>
      8 #include <set>
      9 #include <string>
     10 #include <queue>
     11 #include <stack>
     12 #include <bitset>
     13 using namespace std;
     14 #define pb(x) push_back(x)
     15 #define ll long long
     16 #define mk(x, y) make_pair(x, y)
     17 #define lson l, m, rt<<1
     18 #define mem(a) memset(a, 0, sizeof(a))
     19 #define rson m+1, r, rt<<1|1
     20 #define mem1(a) memset(a, -1, sizeof(a))
     21 #define mem2(a) memset(a, 0x3f, sizeof(a))
     22 #define rep(i, n, a) for(int i = a; i<n; i++)
     23 #define fi first
     24 #define se second
     25 typedef pair<int, int> pll;
     26 const double PI = acos(-1.0);
     27 const double eps = 1e-8;
     28 const int mod = 1e9+7;
     29 const int inf = 1061109567;
     30 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
     31 const int maxn = 2e4+5;
     32 int sa[maxn];
     33 int t1[maxn],t2[maxn],c[maxn], a[maxn];
     34 int rankk[maxn],height[maxn];
     35 void build_sa(int s[],int n,int m)
     36 {
     37     int i,j,p,*x=t1,*y=t2;
     38     for(i=0;i<m;i++)c[i]=0;
     39     for(i=0;i<n;i++)c[x[i]=s[i]]++;
     40     for(i=1;i<m;i++)c[i]+=c[i-1];
     41     for(i=n-1;i>=0;i--)sa[--c[x[i]]]=i;
     42     for(j=1;j<=n;j<<=1)
     43     {
     44         p=0;
     45         for(i=n-j;i<n;i++)y[p++]=i;
     46         for(i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j;
     47         for(i=0;i<m;i++)c[i]=0;
     48         for(i=0;i<n;i++)c[x[y[i]]]++;
     49         for(i=1;i<m;i++)c[i]+=c[i-1];
     50         for(i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i];
     51         swap(x,y);
     52         p=1;x[sa[0]]=0;
     53         for(i=1;i<n;i++)
     54             x[sa[i]]=y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+j]==y[sa[i]+j]?p-1:p++;
     55         if(p>=n)break;
     56         m=p;
     57     }
     58 }
     59 void getHeight(int s[],int n)
     60 {
     61     int i,j,k=0;
     62     for(i=0;i<=n;i++)rankk[sa[i]]=i;
     63     for(i=0;i<n;i++)
     64     {
     65         if(k)k--;
     66         j=sa[rankk[i]-1];
     67         while(s[i+k]==s[j+k])k++;
     68         height[rankk[i]]=k;
     69     }
     70 }
     71 int check(int mid, int n, int m) {
     72     int cnt = 1;
     73     for(int i = 1; i<=n; i++) {
     74         if(height[i]>=mid) {
     75             cnt++;
     76             if(cnt>=m)
     77                 return 1;
     78         } else {
     79             cnt = 1;
     80         }
     81     }
     82     return 0;
     83 }
     84 int main()
     85 {
     86     int n, m;
     87     while(cin>>n>>m) {
     88         int maxx = 0;
     89         for(int i = 0; i<n; i++) {
     90             scanf("%d", &a[i]);
     91             maxx = max(maxx, a[i]);
     92         }
     93         a[n] = 0;
     94         build_sa(a, n+1, maxx+1);
     95         getHeight(a, n);
     96         int l = 1, r = n, ans;
     97         while(l<=r) {
     98             int mid = l+r>>1;
     99             if(!check(mid, n, m)) {
    100                 r = mid-1;
    101             } else {
    102                 l = mid+1;
    103                 ans = mid;
    104             }
    105         }
    106         cout<<ans<<endl;
    107     }
    108     return 0;
    109 }
  • 相关阅读:
    取2个日期间的天数
    C#代码与JAVASCRIPT函数的相互调用
    ASP.NET验证码(3种)
    VS2008自带SQL 2005如何使用
    文本框默认有一个值,然后鼠标点上去那个值就清空
    远程桌面连接会话超时或者被限制改组策略也没用的时候就这么解决
    关于CComboBox的使用,编辑项的文字
    vc 剪切板 unicode
    Linux 防火墙、SELinux 的开启和关闭
    MSSQLSERVER服务不能启动
  • 原文地址:https://www.cnblogs.com/yohaha/p/5098131.html
Copyright © 2011-2022 走看看