`
暴风雪
  • 浏览: 393691 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
社区版块
存档分类
最新评论

[最长公共子串-后缀数组]hdoj 1403:Longest Common Substring

阅读更多

大致题意:
    如题。

 

大致思路:
    后缀数组+二分的简单应用,可以扩展到多串匹配中去

 

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int nMax = 500000;

int  num[nMax];
int sa[nMax], rank[nMax], height[nMax];
int wa[nMax], wb[nMax], wv[nMax], wd[nMax];

int cmp(int *r, int a, int b, int l){
    return r[a] == r[b] && r[a+l] == r[b+l];
}

void da(int *r, int n, int m){          //  倍增算法 r为待匹配数组  n为总长度 m为字符范围
    int i, j, p, *x = wa, *y = wb, *t;
    for(i = 0; i < m; i ++) wd[i] = 0;
    for(i = 0; i < n; i ++) wd[x[i]=r[i]] ++;
    for(i = 1; i < m; i ++) wd[i] += wd[i-1];
    for(i = n-1; i >= 0; i --) sa[-- wd[x[i]]] = i;
    for(j = 1, p = 1; p < n; j *= 2, m = p){
        for(p = 0, 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 < n; i ++) wv[i] = x[y[i]];
        for(i = 0; i < m; i ++) wd[i] = 0;
        for(i = 0; i < n; i ++) wd[wv[i]] ++;
        for(i = 1; i < m; i ++) wd[i] += wd[i-1];
        for(i = n-1; i >= 0; i --) sa[-- wd[wv[i]]] = y[i];
        for(t = x, x = y, y = t, p = 1, x[sa[0]] = 0, i = 1; i < n; i ++){
            x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p - 1: p ++;
        }
    }
}

void calHeight(int *r, int n){           //  求height数组。
    int i, j, k = 0;
    for(i = 1; i <= n; i ++) rank[sa[i]] = i;
    for(i = 0; i < n; height[rank[i ++]] = k){
        for(k ? k -- : 0, j = sa[rank[i]-1]; r[i+k] == r[j+k]; k ++);
    }
}

int loc[nMax];
char str[nMax],res[nMax];
bool vis[1004];

bool check(int mid,int len){
    int i,j,tot;
    tot=0;
    memset(vis,0,sizeof(vis));
    for(i=2;i<=len;i++){
        if(height[i]<mid){
            memset(vis,0,sizeof(vis));
            tot=0;
        }
        else{
            if(!vis[loc[sa[i-1]]]){
                vis[loc[sa[i-1]]]=1;
                tot++;
            }
            if(!vis[loc[sa[i]]]){
                vis[loc[sa[i]]]=1;
                tot++;
            }
            if(tot==2){
//                for(j=0;j<mid;j++){
//                    res[j]=num[sa[i]+j]+'A'-1;
//                }res[mid]='\0';
                return 1;
            }
        }
    }
    return 0;
}

int main(){
    int n,k,i,j,a,b,sp,ans,cas;
   // scanf("%d",&cas);
    while(scanf("%s",str)!=EOF){
        sp=31;    //分隔符
        n=0;
        ans=0;
        for(j=0;str[j];j++){
            loc[n]=1;
            num[n++]=str[j]-'a'+1;
        }
        loc[n]=sp;
        num[n++]=sp++;
        scanf("%s",str);
        for(j=0;str[j];j++){
            loc[n]=2;
            num[n++]=str[j]-'a'+1;
        }
        loc[n]=sp;
        num[n++]=sp++;
        num[n]=0;
        da(num,n+1,sp+1);
        calHeight(num,n);
        int left=0,right=strlen(str),mid;//开始二分
        while(right>=left){
            mid=(right+left)/2;
            if(check(mid,n)){         //判断长度为mid的串是否是所有字符串的公共子串
                left=mid+1;
                ans=mid;
            }
            else{
                right=mid-1;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}
 
0
0
分享到:
评论

相关推荐

    HDOJ-from-zero-to-zero:HDOJ题解(大概。。。)

    HDOJ从零到零 &lt;&lt;&lt; &lt;&lt;&lt; &lt;&lt;&lt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; :calendar:阶段性计划 :bullseye: 2021-04-30〜30题

    最长公共子序列 一个给定序列的子序列是在该序列中删去若干元素后得到的序列。给定两个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。例如,若X={A,B,C,B,D,B,A},Y={B,D,C,A,B,A},则序列{B,C,A}是X和Y的一个公共子序列,但它不是X和Y的一个最长公共子序列。序列{B,C,B,A}也是X和Y的一个公共子序列,它的长度为4,而且它是X和Y的一个最长公共子序列,因为X和Y没有长度大于4的公共子序列。 最长公共

    最长公共子序列(Longest Common Subsequence,简称LCS)问题属于计算机科学领域中的一个重要问题,尤其是在算法设计与分析方面。此问题的核心在于寻找两个序列的最长公共子序列。其中,“子序列”指的是在原序列中...

    leetcode1198-Algorithm:HDOJ、力码

    标题 "leetcode1198-Algorithm:HDOJ、力码" 暗示这是一个关于算法问题的讨论,特别是与LeetCode平台上的第1198题相关的。LeetCode是一个在线平台,提供各种编程挑战,帮助程序员提升算法技能。HDOJ(HDU Online ...

    hdoj2066最短路

    根据给定的文件信息,我们可以总结出以下关于“hdoj2066最短路径”的相关知识点: ## hdoj2066最短路径概述 ### 标题解析:“hdoj2066最短路” - **hdoj**:High Density Online Judge(高密度在线评测系统),是...

    leetcode中国-MyAlgorithmSolutions::balloon:记录我所有的算法/数据结构

    HDOJ LeetCode 程序员面试金典 剑指OFFER PAT 甲级 乙级 ACWing 算法基础班 快排 归并 二分 高精度 前缀和差分 双指针 位运算 离散化 区间合并 单链表 双链表 栈 队列 单调栈 单调队列 KMP Tire 并查集 堆 哈希表 ...

    hdoj杭电入门训练题

    ### hdoj杭电入门训练题 #### 概述 杭电在线评测系统(HDOJ)是中国杭州电子科技大学提供的一套在线编程题库平台,主要用于计算机程序设计竞赛(ACM-ICPC)的训练与选拔。对于初学者而言,通过解决HDOJ中的题目可以...

    leetcode和hdoj-Algorithm-Packages:算法包

    leetcode和hdoj 简介 主要用来记录算法刷题记录和一些模板 文件结构 leetcode 存放leetcode题目和周赛 atcoder 用于存放参与和vp的atcoder比赛 codeforces 用于存放参与和vp的cf比赛,比赛文件夹以比赛序号和div描述...

    hdoj1002——大整数相加

    ### hdoj1002——大整数相加 #### 题目背景与目的 本题目来源于杭州电子科技大学的在线评测系统(HDOJ),编号为1002的大整数相加问题。该题目主要考察的是编程者对于大整数处理的基本技巧以及对数组、循环等基础...

    hdu 部分解题代码 hdoj

    HDU(杭电在线评测系统,也称为HDOJ)是一个知名的在线编程竞赛平台,它提供了许多编程题目供用户练习和提升编程技能。这个压缩包文件“hdu”包含了作者在解决HDU平台上的一些问题时编写的解题代码。下面我们将深入...

    hdoj--acm题目,有注释

    "hdoj--acm题目,有注释" 本资源提供了多个 ACM 题目的解决方案,代码都带有注释,非常适合初学者学习。下面是对每个题目的知识点总结: 2000:本题目要求输入三个字符,输出按照从小到大排序的结果。本代码使用了...

    ACM学习课件-HDOJ

    动态规划是一种强大的解决问题的方法,常用于处理有重叠子问题和最优子结构的问题,如背包问题、最长公共子序列等。学习动态规划不仅需要理解状态转移方程,还需要培养构造状态和状态转移矩阵的能力。 贪心算法和...

    HDOJ题目分类 HDOJ题目分类

    【标题】:“HDOJ题目分类 HDOJ题目分类” HDOJ,全称为Happy DingO Online Judge,是一个在线编程竞赛平台,它为参赛者提供了大量编程题目进行练习和比赛,旨在提升编程技能和算法理解。HDOJ的题目分类是帮助用户...

    求回文子串_O(n)_manacher算法

    例如,在解决HDOJ_3068_最长回文子串问题时,Manacher算法能够快速准确地找出给定字符串中的最长回文子串,为各种文本分析、模式匹配等任务提供了高效的解决方案。 综上所述,Manacher算法作为一种专门针对回文子串...

    hdoj 2013 多校训练2标程+解题报告

    “hdoj 2013 多校训练2标程+解题报告”这个标题指的是2013年举行的一场由hdoj(HDU Online Judge,即杭州电子科技大学在线评测系统)组织的多校联合编程训练活动的第二阶段。其中,“标程”是指官方提供的正确解答...

    hdoj1005 Number Sequence 代码

    ### hdoj1005 Number Sequence 代码分析与解析 #### 一、问题背景与题目概述 在深入了解代码之前,我们先来了解下题目背景。`hdoj1005 Number Sequence` 是杭州电子科技大学在线评测系统(Online Judge,简称OJ)...

    ACM-ICPC-OJ-Code:流行的在线裁判系统的一些解决方案代码

    我的解决方案代码适用于流行的在线裁判系统,例如 POJ、HDOJ、SGU 和 ACM-ICPC Live Archive。 但是,我忘记了我用来解决这些问题的算法! 我将通过竞赛来组织代码和解决方案。 一些索引页面将可用,以便您可以更快...

    HDOJ1003

    ACM ICPC HDOJ1003

    HDOJ 80题 Java

    【标题】"HDOJ 80题 Java"是一份专为Java程序员设计的在线编程挑战集合,源自杭州电子科技大学(HDOJ)的在线评测系统。这些题目旨在帮助Java开发者提升算法理解与编程能力,同时也为那些习惯于C++但希望在Java环境...

    HDOJ.rar_HD_HDOJ

    【标题】"HDOJ.rar_HD_HDOJ" 是一个与HDU(杭州电子科技大学)在线判题系统HDOJ相关的压缩包文件,其中包含了大量编程题目的源代码。 【描述】提到,这个压缩包包含了几百道HDOJ题目的源代码,这意味着它是一个宝贵...

    hdoj杭电1000-2000部分解题报告

    “hdoj杭电1000-2000部分解题报告”这个标题指的是一个关于杭州电子科技大学(简称杭电)在线编程竞赛平台(HDU Online Judge,简称HDOJ)上的题目解题报告。这份报告涵盖了编号从1000到2000的题目,这是一段相当大...

Global site tag (gtag.js) - Google Analytics