• [BJWC2010] 外星联络


    [BJWC2010] 外星联络

    Description

    求一个 (01) 串中所有重复出现次数大于 (1) 的子串所出现的次数,按照字典序排序输出。

    Solution

    预处理出后缀数组和高度数组。

    对于每一个后缀 (i) ,如果 (h[i+1]>h[i]) ,我们就去找到在这之后对任意 (j in (h[i], h[i+1]]) ,第一次出现 (h[k]<j)(k) ,那么 (k-i) 就是这个子串出现的次数。

    很不优美的解法,但是好像又没有别的办法。还不如直接建字典树。

    #include <bits/stdc++.h>
    using namespace std;
    
    int n,m=256,sa[1000005],y[1000005],u[1000005],v[1000005],o[1000005],r[1000005],h[1000005],T;
    
    char str[1000005];
    long long ans;
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin>>n;
        cin>>str+1;
    
        for(int i=1; i<=n; i++) u[str[i]]++;
        for(int i=1; i<=m; i++) u[i]+=u[i-1];
        for(int i=n; i>=1; i--) sa[u[str[i]]--]=i;
        r[sa[1]]=1;
        for(int i=2; i<=n; i++) r[sa[i]]=r[sa[i-1]]+(str[sa[i]]!=str[sa[i-1]]);
    
        for(int l=1; r[sa[n]]<n; l<<=1)
        {
            memset(u,0,sizeof u);
            memset(v,0,sizeof v);
            memcpy(o,r,sizeof r);
            for(int i=1; i<=n; i++) u[r[i]]++, v[r[i+l]]++;
            for(int i=1; i<=n; i++) u[i]+=u[i-1], v[i]+=v[i-1];
            for(int i=n; i>=1; i--) y[v[r[i+l]]--]=i;
            for(int i=n; i>=1; i--) sa[u[r[y[i]]]--]=y[i];
            r[sa[1]]=1;
            for(int i=2; i<=n; i++) r[sa[i]]=r[sa[i-1]]+((o[sa[i]]!=o[sa[i-1]])||(o[sa[i]+l]!=o[sa[i-1]+l]));
        }
        {
            int i,j,k=0;
            for(int i=1; i<=n; h[r[i++]]=k)
                for(k?k--:0,j=sa[r[i]-1]; str[i+k]==str[j+k]; k++);
        }
    
        for(int i=1; i<=n; i++)
        {
            int l=h[i],r=h[i+1];
            if(l<r)
            {
                //cout<<"l="<<l<<" r="<<r<<endl;
                vector <int> tmp;
                ++l;
                for(int j=i+1; j<=n+1 && l<=r; j++)
                {
                    while(r>h[j]&&l<=r)
                    {
                        tmp.push_back(j-i);
                        --r;
                    }
                }
                for(int j=tmp.size()-1; j>=0; --j)
                    cout<<tmp[j]<<endl;
            }
        }
    }
    
  • 相关阅读:
    线程安全
    C++和java中构造函数与析构函数的调用顺序
    mysql数据库的备份与恢复
    Spring Web Flow 2.0 入门详解
    JBOSS 5.0与tomcat 6.0端口设置
    修改mysql root密码
    Subversion Native Library Not Available
    解决Eclipse导入svn项目自动关闭
    将eclipse中项目的Text File Encoding设置成为GBK
    java下实现调用oracle的存储过程和函数
  • 原文地址:https://www.cnblogs.com/mollnn/p/11756866.html
Copyright © 2020-2023  润新知