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;
    }

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

  • 相关阅读:
    Fluent 18.0新功能之:其他
    【小白的CFD之旅】小结及预告
    【小白的CFD之旅】19 来自计算网格的困惑
    【小白的CFD之旅】18 控制方程基础
    【小白的CFD之旅】23 串行与并行
    【小白的CFD之旅】22 好网格与坏网格
    JS ES6的变量的结构赋值
    JS中some()和every()和join()和concat()和pop(),push(),shift(),unshfit()和map()和filter()
    JS(原生js和jq方式)获取元素属性(自定义属性),删除属性(自定义属性)
    javascript中this的指向问题
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/5136329.html
Copyright © 2011-2022 走看看