zoukankan      html  css  js  c++  java
  • UVALive 6869(后缀数组)

    传送门:Repeated Substrings

    题意:给定一个字符串,求至少重复一次的不同子串个数。

    分析:模拟写出子符串后缀并排好序可以发现,每次出现新的重复子串个数都是由现在的height值减去前一个height值。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    const int maxn = 100010;
    typedef long long LL;
    int sa[maxn];
    int t1[maxn], t2[maxn], c[maxn];
    int ran[maxn], height[maxn];
    int s[maxn];
    char str[maxn];
    
    void build_sa(int s[], int n, int m) {
        int i, j, p, *x = t1, *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 (j = 1; j <= n; j <<= 1) {
            p = 0;
            for (i = n-j; i < n; i++) y[p++] = i;
            for (i = 0; i < n; i++)
                if (sa[i] >= j)
                    y[p++] = sa[i] - j;
            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 (i = 1; i < n; i++)
                x[sa[i]] = y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+j] == y[sa[i]+j] ? p-1 : p++;
    
            if (p >= n) break;
            m = p;
        }
    }
    
    void getHeight(int s[],int n) {
        int i, j, k = 0;
        for (i = 0; i <= n; i++)
            ran[sa[i]] = i;
        for (i = 0; i < n; i++) {
            if (k) k--;
            j = sa[ran[i]-1];
            while (s[i+k] == s[j+k]) k++;
            height[ran[i]]=k;
        }
    }
    int main() {
        int T;
        scanf("%d", &T);
        while (T--) {
            scanf("%s", str);
            int n = strlen(str);
            for (int i = 0; i <= n; i++)
                s[i] = str[i];
            build_sa(s, n+1, 128);
            getHeight(s, n);
            LL ans = 0;
            for (int i = 1; i <= n; i++)
            {
                if(height[i]>height[i-1])ans+=height[i]-height[i-1];
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ABAP-FI-Redirection of read accesses from ANEA to FAAV_ANEA failed
    招聘
    五分钟教你在长沙如何找到靠谱的驾校和教练(长沙找驾校)
    数组哪些方法能改变原数组,以及循环改变数组的情况
    FXGL游戏开发-JavaFX游戏框架
    tempermonkey.d.ts | 油猴函数类型
    post导出文件
    mescroll.js 使用
    查看托管应用池用法
    IDEA配置
  • 原文地址:https://www.cnblogs.com/lienus/p/4459801.html
Copyright © 2011-2022 走看看