zoukankan      html  css  js  c++  java
  • POJ 2774 Long Long Message

    一句话题意:求给定两个字符串的最长公共子串的长度。

    我们后缀数组的\(H\)数组显然有这个性质。就将两个串拼在一起,注意中间加一个不会出现的符号,因为可能会求到跨越\(A\)串与\(B\)串的“子串”就会出问题。(但是亲测不加也能\(A\)

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    const int N = 200002;
    
    int n, m, h[N], tax[N], SA[N], tp[N], rk[N], a[N];
    
    int read() {
    	int x = 0, f = 1; char S;
    	while((S = getchar()) > '9' || S < '0') {
    		if(S == '-') f = -1;
    		if(S == EOF) exit(0);
    	}
    	while(S <= '9' && S >= '0') {
    		x = (x << 1) + (x << 3) + (S ^ 48);
    		S = getchar();
    	}
    	return x * f;
    }
    
    bool cmp(const int x, const int y, const int d) {return tp[x] == tp[y] && tp[x + d] == tp[y + d];}
    
    void Sort() {
        for(int i = 0; i <= m; ++ i) tax[i] = 0;
        for(int i = 1; i <= n; ++ i) ++ tax[rk[tp[i]]];
        for(int i = 1; i <= m; ++ i) tax[i] += tax[i - 1];
        for(int i = n; i >= 1; -- i) SA[tax[rk[tp[i]]] --] = tp[i];
    }
    
    void Suffix() {
        for(int i = 1; i <= n; ++ i) rk[i] = a[i], tp[i] = i;
        m = 122; Sort();
        for(int w = 1, p = 1, i; p < n; m = p, w <<= 1) {
            for(p = 0, i = n - w + 1; i <= n; ++ i) tp[++ p] = i;
            for(i = 1; i <= n; ++ i) if(SA[i] > w) tp[++ p] = SA[i] - w;
            Sort(); swap(rk, tp); rk[SA[1]] = p = 1;
            for(i = 2; i <= n; ++ i) rk[SA[i]] = cmp(SA[i], SA[i - 1], w) ? p : ++ p;
        }
        int j, k = 0;
        for(int i = 1; i <= n; h[rk[i ++]] = k)
            for(k = k ? k - 1 : k, j = SA[rk[i] - 1]; a[i + k] == a[j + k]; ++ k);
    }
    
    int main() {
        char ch[N];
        int ans = 0, tmp;
        scanf("%s", ch); n = strlen(ch);
        for(int i = 0; i < n; ++ i) a[i + 1] = ch[i];
        scanf("%s", ch);
        tmp = n;
        a[n + 1] = '#'; ++ n;
        for(int i = n + 1, siz = strlen(ch); i <= n + siz; ++ i) a[i] = ch[i - n - 1];
        n += strlen(ch); Suffix();
        for(int i = 2; i <= n; ++ i)
            if(1ll * (SA[i] - tmp - 1) * (SA[i - 1] - tmp - 1) < 0) ans = max(ans, h[i]);
        printf("%d\n", ans);
        return 0;
    }
    
  • 相关阅读:
    大三学习进度64
    大三学习进度70
    中美科技巨头——BATH和GAFA
    多线程写excel数据思路
    3
    1
    比特币
    加分项
    3e
    换题了
  • 原文地址:https://www.cnblogs.com/AWhiteWall/p/12383292.html
Copyright © 2011-2022 走看看