• POJ2774


    题意:给定两个字符串,求两个串的最长公共子路。两个串的长度不超过100000。

    算法:把两个串用一个连接符连接起来,然后求height[]和sa[],扫描height[],如果sa[i]和sa[i-1]分别在两个串中的最大hgight[]的值。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 using namespace std;
     5 const int maxn=200010;
     6 char c[100005],cc[100005];
     7 int s[maxn],sa[maxn],rank[maxn],height[maxn],saf[maxn],cs[maxn];
     8 int n,m,mid;
     9 void init()
    10 {
    11     scanf("%s",c);scanf("%s",cc);
    12     int p=0;
    13     for(int i=0;c[i];++i)s[++p]=c[i];++p;
    14     mid=p;
    15     for(int i=0;cc[i];++i)s[++p]=cc[i];
    16     n=p;
    17     s[0]=s[n+1]=-1;
    18 }
    19 void rsort()
    20 {
    21     for(int i=0;i<=m;++i)cs[i]=0;
    22     for(int i=1;i<=n;++i)cs[rank[saf[i]]]++;
    23     for(int i=1;i<=m;++i)cs[i]+=cs[i-1];
    24     for(int i=n;i>=1;--i)sa[cs[rank[saf[i]]]--]=saf[i];
    25 }
    26 int cmp(int *f,int x,int y,int w)
    27 {
    28     return f[x]==f[y] && f[x+w]==f[y+w];
    29 }
    30 void suffix()
    31 {
    32     for(int i=1;i<=n;++i)rank[i]=s[i],saf[i]=i;
    33     m=127;rsort();
    34     for(int p=1,w=1,i;p<n;w<<=1,m=p)
    35     {
    36         for(i=n-w+1,p=0;i<=n;++i)saf[++p]=i;
    37         for(i=1;i<=n;++i)if(sa[i]>w)saf[++p]=sa[i]-w;
    38         rsort();swap(rank,saf);rank[sa[1]]=p=1;
    39         for(i=2;i<=n;++i)rank[sa[i]]=cmp(saf,sa[i],sa[i-1],w)?p:++p;
    40     }
    41     int j,k=0;
    42     for(int i=1;i<=n;height[rank[i++]]=k)
    43         for(k=k?k-1:k,j=sa[rank[i]-1];s[i+k]==s[j+k];++k);
    44 }
    45 bool ind1(int x)
    46 {
    47     return x>=1 &&x<mid;
    48 }
    49 bool ind2(int x)
    50 {
    51     return x>mid && x<=n;
    52 }
    53 void work()
    54 {
    55     int ans=0;
    56     for(int i=2;i<=n;++i)
    57     if(height[i]>ans && ((ind1(sa[i]) && ind2(sa[i-1]))||(ind2(sa[i]) && ind1(sa[i-1]))))
    58     ans=height[i];
    59     cout<<ans;
    60 }
    61 int main()
    62 {
    63     init();
    64     suffix();
    65     work();
    66     return 0;
    67 }
  • 相关阅读:
    麻省理工算法导论学习笔记(1)算法介绍
    麻省理工算法导论学习笔记(2)渐近符号、递归及解法
    Mybatis if 标签 判断不生效
    Linux permission denied解决方法?
    MySQL查找是否存在
    List集合数据去重
    Java获取list集合的前几个元素
    git如何新建(修改)分支
    asp.net下url参数含有中文读取后为乱码
    时间复杂度为O(n)的排序算法
  • 原文地址:https://www.cnblogs.com/gryzy/p/8287787.html
Copyright © 2020-2023  润新知