zoukankan      html  css  js  c++  java
  • 最长公共子串 (输出子串)

    题目链接:https://cn.vjudge.net/contest/318888#problem/I

    题意:

    求两个字符串的最长公共子串并且输出

    思路:

    和求最长公共子串的思路是一样的,就是多一个记录位置的操作。

      1 #include <stdio.h>
      2 #include <iostream>
      3 #include <algorithm>
      4 #include <string.h>
      5 #include <stdlib.h>
      6 #include <math.h>
      7 #include <queue>
      8 #include <set>
      9 
     10 #define INF 0x3f3f3f3f
     11 #define pii pair<int,int>
     12 #define LL long long
     13 using namespace std;
     14 typedef unsigned long long ull;
     15 const int MAXN = 200005;
     16 
     17 int wa[MAXN], wb[MAXN], wv[MAXN], ws_[MAXN];
     18 void Suffix(int *r, int *sa, int n, int m)
     19 {
     20     int i, j, k, *x = wa, *y = wb, *t;
     21     for(i = 0; i < m; ++i) ws_[i] = 0;
     22     for(i = 0; i < n; ++i) ws_[x[i] = r[i]]++;
     23     for(i = 1; i < m; ++i) ws_[i] += ws_[i - 1];
     24     for(i = n - 1; i >= 0; --i) sa[--ws_[x[i]]] = i;
     25     for(j = 1, k = 1; k < n; j *= 2, m = k)
     26     {
     27         for(k = 0, i = n - j; i < n; ++i) y[k++] = i;
     28         for(i = 0; i < n; ++i) if(sa[i] >= j) y[k++] = sa[i] - j;
     29         for(i = 0; i < n; ++i) wv[i] = x[y[i]];
     30         for(i = 0; i < m; ++i) ws_[i] = 0;
     31         for(i = 0; i < n; ++i) ws_[wv[i]]++;
     32         for(i = 1; i < m; ++i) ws_[i] += ws_[i - 1];
     33         for(i = n - 1; i >= 0; --i) sa[--ws_[wv[i]]] = y[i];
     34         t = x;
     35         x = y;
     36         y = t;
     37         for(x[sa[0]] = 0, i = k = 1; i < n; ++i)
     38             x[sa[i]] = (y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + j] == y[sa[i] + j]) ? k - 1 : k++;
     39     }
     40 }
     41 int Rank[MAXN], height[MAXN], sa[MAXN], r[MAXN];
     42 void calheight(int *r,int *sa,int n)
     43 {
     44     int i,j,k=0;
     45     for(i=1; i<=n; i++)Rank[sa[i]]=i;
     46     for(i=0; i<n; height[Rank[i++]]=k)
     47         for(k?k--:0,j=sa[Rank[i]-1]; r[i+k]==r[j+k]; k++);
     48 }
     49 int n,minnum[MAXN][17];
     50 void RMQ()
     51 {
     52     int i,j;
     53     int m=(int)(log(n*1.0)/log(2.0));
     54     for(i=1;i<=n;i++)
     55         minnum[i][0]=height[i];
     56     for(j=1;j<=m;j++)
     57         for(i=1;i+(1<<j)-1<=n;i++)
     58             minnum[i][j]=min(minnum[i][j-1],minnum[i+(1<<(j-1))][j-1]);
     59 }
     60 int Ask_MIN(int a,int b)
     61 {
     62     int k=int(log(b-a+1.0)/log(2.0));
     63     return min(minnum[a][k],minnum[b-(1<<k)+1][k]);
     64 }
     65 int calprefix(int a,int b)
     66 {
     67     a=Rank[a],b=Rank[b];
     68     if(a>b)
     69         swap(a,b);
     70     return Ask_MIN(a+1,b);
     71 }
     72 char s[MAXN];
     73 int q[MAXN];
     74 int main()
     75 {
     76     int k;
     77     cin >> k;
     78     cin >> s;
     79     s[k] = '#';
     80     cin >> (s+k+1);
     81     int n = strlen(s);
     82     for (int i=0;i<n;i++){
     83         r[i] = s[i];
     84     }
     85     int maxx = 0;
     86     Suffix(r,sa,n+1,258);
     87     calheight(r,sa,n);
     88     int x,y;
     89     for (int i=1;i<=n;i++) {
     90         if (height[i] > maxx && 1ll * (sa[i] - k) * (sa[i - 1] - k) < 0){
     91             maxx = height[i];
     92             x = min(sa[i],sa[i-1]);
     93             y = x+maxx;
     94         }
     95     }
     96     for (int i=x;i<y;i++){
     97         printf("%c",s[i]);
     98     }
     99     return 0;
    100 }
  • 相关阅读:
    hdu 3342 Legal or Not 拓排序
    hdu 1596 find the safest road Dijkstra
    hdu 1874 畅通工程续 Dijkstra
    poj 2676 sudoku dfs
    poj 2251 BFS
    poj Prime Path BFS
    poj 3278 BFS
    poj 2387 Dijkstra 模板
    poj 3083 DFS 和BFS
    poj 1062 昂贵的聘礼 dijkstra
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/11337534.html
Copyright © 2011-2022 走看看