• 不小于k个字符串的最长子串


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

    题意:

    给你n个字符串,求至少出现在向上取整n/2的个串的公共子串如果有多个就输出多个。

    思路:

      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 
     50 char s[MAXN];
     51 int vis[MAXN];
     52 int indexx[MAXN];
     53 int T;
     54 vector<int> ans[MAXN];
     55 
     56 bool check(int x,int n){
     57     for (int i=1;i<n;i++) {
     58         if (height[i] < x)
     59             continue;
     60         int cnt = 0;
     61         for (int j = 0; j <= T; j++) {
     62             vis[j] = 0;
     63         }
     64         while (height[i] >= x && i < n) {
     65             if (!vis[indexx[sa[i - 1]]]) {
     66                 vis[indexx[sa[i - 1]]] = 1;
     67                 cnt++;
     68             }
     69             i++;
     70         }
     71         if (!vis[indexx[sa[i - 1]]]) {
     72             vis[indexx[sa[i - 1]]] = 1;
     73             cnt++;
     74         }
     75         if (cnt > T / 2) {
     76             ans[x].push_back(sa[i - 1]);
     77         }
     78     }
     79     if(ans[x].size()!=0) return true;
     80     return false;
     81 }
     82 
     83 
     84 int main()
     85 {
     86     while (~scanf("%d",&T) && T) {
     87         for (int i=0;i<=1000;i++){
     88             ans[i].clear();
     89         }
     90         int XX = 30;
     91         int n = 0;
     92         for (int i=0;i<T;i++){
     93             scanf("%s",s);
     94             int len = strlen(s);
     95             for (int j=0;j<len;j++){
     96                 r[n++] = s[j]-'a'+1;
     97                 indexx[n-1] = i;
     98             }
     99             r[n++] = XX++;
    100         }
    101         r[n] = 0;
    102         Suffix(r,sa,n+1,250);
    103         calheight(r,sa,n);
    104         int L=1,R=1000,mid,len=0;
    105         while (L<=R){
    106             mid = (L+R)>>1;
    107             if (check(mid,n)){
    108                 len = mid;
    109                 L = mid+1;
    110             }else
    111                 R = mid-1;
    112         }
    113         if(len==0) printf("?
    ");
    114         else
    115         {
    116             for(int i=0;i<ans[len].size();i++)
    117             {
    118                 for(int j=ans[len][i];j<ans[len][i]+len;j++)
    119                     printf("%c",(char)r[j]+'a'-1);
    120                 printf("
    ");
    121             }
    122         }
    123         cout<<endl;
    124     }
    125     return 0;
    126 }
  • 相关阅读:
    升级到`Google-Mobile-Ads-SDK(->7.68)`,导出Unity工程产生的几个BUG以及解决办法
    unity中Asset Store下载的资源保存位置
    Maven打包报错 No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?
    C# ISharpZipLib 压缩/解压缩zip文件
    jarsigner.exe 命令行出现乱码的解决办法
    SwiftUI 结构体自动生成可编辑界面
    .Net Mvc ActionFilterAttribute的OnActionExecuted中获取请求参数信息
    .netcore Attribute特性使用 TypeFilter传参
    vue router.app.$store undefined
    js 判断点击是否是某个div下的dom
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/11343525.html
Copyright © 2020-2023  润新知