zoukankan      html  css  js  c++  java
  • SPOJ

    D - New Distinct Substrings

     题目大意:求一个字符串中不同子串的个数。

    裸的后缀数组

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define pii pair<int, int>
    #define y1 skldjfskldjg
    #define y2 skldfjsklejg
    
    using namespace std;
    
    const int N = 1e5 + 7;
    const int M = 1e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    
    char s[N];
    int sa[N], t[N], t2[N], c[N], rk[N], height[N], id[N], b[N], d[N], n, tot;
    
    void buildSa(char *s, int n, int m) {
        int i, j = 0, k = 0, *x = t, *y = t2;
        for(i = 0; i < m; i++) c[i] = 0;
        for(i = 0; i < n; i++) c[x[i] = s[i]]++;
        for(i = 1; i < m; i++) c[i] += c[i - 1];
        for(i = n - 1; i >= 0; i--) sa[--c[x[i]]] = i;
        for(int k = 1; k <= n; k <<= 1) {
            int p = 0;
            for(i = n - k; i < n; i++) y[p++] = i;
            for(i = 0; i < n; i++) if(sa[i] >= k) y[p++] = sa[i] - k;
            for(i = 0; i < m; i++) c[i] = 0;
            for(i = 0; i < n; i++) c[x[y[i]]]++;
            for(i = 1; i < m; i++) c[i] += c[i - 1];
            for(i = n - 1; i >= 0; i--) sa[--c[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 - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k])
                    x[sa[i]] = p - 1;
                else x[sa[i]] = p++;
            }
            if(p >= n) break;
            m = p;
         }
    
         for(i = 1; i < n; i++) rk[sa[i]] = i;
         for(i = 0; i < n - 1; i++) {
            if(k) k--;
            j = sa[rk[i] - 1];
            while(s[i + k] == s[j + k]) k++;
            height[rk[i]] = k;
         }
    }
    
    
    int main() {
        int T; scanf("%d", &T);
        while(scanf("%s", s) != EOF) {
    
            n = strlen(s);
            buildSa(s, n + 1, 180);
    
            LL ans = 0;
    
            for(int i = 1; i <= n; i++) {
                ans += (n - sa[i]) - height[i];
            }
    
            printf("%lld
    ", ans);
        }
        return 0;
    }
    
    
    /*
    */
  • 相关阅读:
    HDU1720 A+B Coming
    HDU1390 ZOJ1383 Binary Numbers
    HDU1390 ZOJ1383 Binary Numbers
    HDU2504 又见GCD
    HDU2504 又见GCD
    HDU1335 POJ1546 UVA389 UVALive5306 ZOJ1334 Basically Speaking
    HDU1335 POJ1546 UVA389 UVALive5306 ZOJ1334 Basically Speaking
    HDU1020 ZOJ2478 Encoding
    HDU1020 ZOJ2478 Encoding
    HDU2097 Sky数
  • 原文地址:https://www.cnblogs.com/CJLHY/p/9343689.html
Copyright © 2011-2022 走看看