• POJ 3415


    一道字符串的题。
    求两个字符串的长度大于K的子串中,相同的有多少对。

    知道了要用到后缀数组,可是想了好久也没想好怎么使用。最后看了一下论文,提到了两个字符串可以合并,中间加上一个特殊字符就可以了。|
    虽然这样还是写了好长时间啊。。。

    首先是合并,然后建立后缀数组,求出sa[],height[],然后在进行加和,用到了一个题解称作单调栈的东西。不知是什么,反正就是合并嘛。
    分别对于两个串进行加和。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    #define maxn 200010
    #define LL long long
    
    int rank[maxn], sa[maxn], t1[maxn], t2[maxn], sum[maxn], h[maxn];
    char c[maxn];
    
    void solve()
    {
        int *x = t1;
        int *y = t2;
        int m = 128;
        int l = strlen(c);
        for(int i = 0; i < m; i++) sum[i] = 0;
        for(int i = 0; i <= l; i++) sum[x[i]=c[i]]++;
        for(int i = 1; i < m; i++) sum[i] += sum[i-1];
        for(int i = l; i >= 0; i--) sa[--sum[x[i]]] = i;
        for(int j = 1; j <= l; j <<= 1)
        {
            int num = 0;
            for(int i = l-j+1; i<=l; i++) y[num++] = i;
            for(int i = 0; i <= l; i++) if(sa[i] >= j) y[num++] = sa[i] - j;
    
            for(int i = 0; i < m; i++) sum[i] = 0;
            for(int i = 0; i <= l; i++) sum[x[i]]++;
            for(int i = 1; i < m; i++) sum[i] += sum[i-1];
            for(int i = l; i >= 0; i--) sa[--sum[x[y[i]]]] = y[i];
    
            swap(x,y);
            m = 1;
            x[sa[0]] = 0;
            for(int i = 1; i <= l; i++)
                x[sa[i]] = (y[sa[i]] == y[sa[i-1]] && y[sa[i]+j] == y[sa[i-1]+j]) ? m-1:m++;
            if(m > l)
                break;
        }
        m = 0;
        for(int i = 0; i <= l; i++) rank[sa[i]] = i;
        for(int i = 0; i < l; i++)
        {
            if(m) m--;
            int j = sa[rank[i]-1];
            while(c[i+m] == c[j+m]) m++;
            h[rank[i]] = m;
        }
    }
    
    int main()
    {
        //freopen("in.txt", "r", stdin);
        //freopen("out(2).txt", "w", stdout);
        int n;
        while(scanf("%d", &n) && n)
        {
            scanf("%s", c);
            int l1 = strlen(c);
            c[l1] = 1;
            scanf("%s", c+l1+1);
            int l2 = strlen(c);
            c[l2] = 0;
            solve();
            LL ans = 0;
            LL sum2 = 0;
            int l = 0;
            for(int i = 1; i <= l2; i++)
            {
                if(h[i] < n)
                {
                    l = 0;
                    sum2 = 0;
                }
                else
                {
                    int tmp = 0;
                    while(l && t1[l-1] >= h[i])
                    {
                        l--;
                        tmp += t2[l];
                        sum2 -= t2[l] * (t1[l] - h[i]);
                    }
                    t1[l] = h[i];
                    t2[l++] = tmp;
                    if(sa[i-1] > l1)
                    {
                        t2[l-1]++;
                        sum2 += h[i]- n + 1;
                    }
                    if(sa[i] < l1)
                    ans += sum2;
                }
            }
            l = 0;
            sum2 = 0;
            for(int i = 1; i <= l2; i++)
            {
                if(h[i] < n)
                {
                    l = 0;
                    sum2 = 0;
                }
                else
                {
                    int tmp = 0;
                    while(l && t1[l-1] >= h[i])
                    {
                        l--;
                        tmp += t2[l];
                        sum2 -= t2[l] * (t1[l] - h[i]);
                    }
                    t1[l] = h[i];
                    t2[l++] = tmp;
                    if(sa[i-1] < l1)
                    {
                        t2[l-1]++;
                        sum2 += h[i] - n + 1;
                    }
                    if(sa[i] > l1)
                    ans += sum2;
                }
            }
           cout << ans << endl;
        }
    }
    View Code

    这样的话对于求最长回文字串我也会了。。。
    不过是将第二个串换成是它的逆序,然后找到最长的

  • 相关阅读:
    选择主要的构建实践方法(转) Tech
    201671010109 201620172《java程序设计》第一周感想
    201671010109 201720162第二周学习感想
    2016710101090 20162017《java程序设计》第三周感想
    sort k 详解
    java.util.NoSuchElementException: None.get的解决方法
    Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace 解决方法
    Java学习随笔之1: Java 语言概述和开发环境
    java 学习随笔之2:理解面向对象
    Selenium Basic Knowledge
  • 原文地址:https://www.cnblogs.com/ye8370/p/3910851.html
Copyright © 2020-2023  润新知