zoukankan      html  css  js  c++  java
  • SDOI2008 Sandy的卡片( 后缀数组 )

    求出后缀数组, 然后二分答案, 对height数组分组检验答案. 时间复杂度O(|S| log|S|)

    --------------------------------------------------------------------------------

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<algorithm>
     
    using namespace std;
     
    const int maxn = 1009;
    const int maxN = 1000009;
     
    inline int read() {
    char c = getchar();
    for(; !isdigit(c); c = getchar());
    int ret = 0;
    for(; isdigit(c); c = getchar())
    ret = ret * 10 + c - '0';
    return ret;
    }
     
    bool vis[maxn];
    int str[maxn][maxn], len[maxn], n, Top;
    int S[maxN], Id[maxN], stk[maxN], N;
    int cnt[maxN], Sa[maxN], Height[maxN], Rank[maxN];
     
    void Build(int m) {
    int *x = Height, *y = Rank;
    for(int i = 0; i < m; i++) cnt[i] = 0;
    for(int i = 0; i < N; i++) cnt[x[i] = S[i]]++;
    for(int i = 1; i < m; i++) cnt[i] += cnt[i - 1];
    for(int i = N; i--; ) Sa[--cnt[x[i]]] = i;
    for(int k = 1, p = 0; k <= N; k <<= 1, p = 0) {
    for(int i = N - k; i < N; i++) y[p++] = i;
    for(int i = 0; i < N; i++)
    if(Sa[i] >= k) y[p++] = Sa[i] - k;
    for(int i = 0; i < m; i++) cnt[i] = 0;
    for(int i = 0; i < N; i++) cnt[x[y[i]]]++;
    for(int i = 1; i < m; i++) cnt[i] += cnt[i - 1];
    for(int i = N; i--; ) Sa[--cnt[x[y[i]]]] = y[i];
    swap(x, y);
    p = 1;
    x[Sa[0]] = 0;
    for(int i = 1; i < N; i++) {
    if(y[Sa[i]] != y[Sa[i - 1]] || y[Sa[i] + k] != y[Sa[i - 1] + k]) p++;
    x[Sa[i]] = p - 1;
    }
    if(p >= N) break;
    m = p;
    }
    for(int i = 0; i < N; i++) Rank[Sa[i]] = i;
    Height[0] = 0;
    for(int i = 0, h = 0; i < N; i++) if(Rank[i]) {
    if(h) h--;
    while(S[i + h] == S[Sa[Rank[i] - 1] + h]) h++;
    Height[Rank[i]] = h;
    }
    }
     
    void Init() {
    int mn = 1 << 30, mx = -1 << 30;
    n = read();
    for(int i = 0; i < n; i++) {
    len[i] = read();
    for(int j = 0; j < len[i]; j++) str[i][j] = read();
    for(int j = len[i]; --j; ) {
    str[i][j] -= str[i][j - 1];
    mn = min(mn, str[i][j]);
    mx = max(mx, str[i][j]);
    }
    }
    N = 0;
    for(int i = 0; i < n; i++) {
    for(int j = 1; j < len[i]; j++) {
    S[N] = str[i][j] - mn + n;
    Id[N++] = i;
    }
    S[N] = n - i - 1;
    Id[N++] = n;
    }
    Build(mx - mn + n + 1);
    memset(vis, 0, sizeof vis);
    vis[n] = 1;
    Top = 0;
    }
     
    bool chk(int v) {
    while(Top) vis[stk[--Top]] = 0;
    for(int i = 1; i < N; i++) if(Height[i] >= v) {
    if(!vis[Id[Sa[i - 1]]])
    vis[stk[Top++] = Id[Sa[i - 1]]] = 1;
    if(!vis[Id[Sa[i]]])
    vis[stk[Top++] = Id[Sa[i]]] = 1;
    if(Top >= n) return true;
    } else {
    while(Top) vis[stk[--Top]] = 0;
    }
    return false;
    }
     
    void Work() {
    int l = 1, r = maxN, ans = 0;
    while(l <= r) {
    int m = (l + r) >> 1;
    if(chk(m)) {
    ans = m, l = m + 1;
    }
    else
    r = m - 1;
    }
    printf("%d ", ++ans);
    }
     
    int main() {
    Init();
    Work();
    return 0;
    }

    -------------------------------------------------------------------------------- 

  • 相关阅读:
    Smart Client Architecture and Design Guide
    Duwamish密码分析篇, Part 3
    庆贺发文100篇
    .Net Distributed Application Design Guide
    New Introduction to ASP.NET 2.0 Web Parts Framework
    SPS toplevel Site Collection Administrators and Owners
    来自Ingo Rammer先生的Email关于《Advanced .Net Remoting》
    The newsletter published by Ingo Rammer
    深度探索.Net Remoting基础架构
    信道、接收器、接收链和信道接受提供程序
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/5136329.html
Copyright © 2011-2022 走看看