zoukankan      html  css  js  c++  java
  • 每个字符串至少出现两次且不重复的最长子串

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

    思路:

      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 = 2e5 + 10;
     16 int t;
     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 char s[MAXN];
     43 int indexx[MAXN],vis[MAXN];
     44 void calheight(int *r,int *sa,int n)
     45 {
     46     int i,j,k=0;
     47     for(i=1; i<=n; i++)Rank[sa[i]]=i;
     48     for(i=0; i<n; height[Rank[i++]]=k)
     49         for(k?k--:0,j=sa[Rank[i]-1]; r[i+k]==r[j+k]; k++);
     50 }
     51 
     52 struct Node{
     53     int cnt,maxsa,minsa;
     54     void init(){
     55         cnt = 0;
     56         maxsa = -1;
     57         minsa = MAXN;
     58     }
     59 }node[20];
     60 
     61 bool check(int x,int n){
     62     int tot = 0;
     63     int idx,lidx;
     64     for (int i=0;i<t;i++){
     65         node[i].init();
     66     }
     67     memset(vis,0, sizeof(vis));
     68     for (int i=1;i<n;i++){
     69         idx = indexx[sa[i]],lidx = indexx[sa[i-1]];
     70         if (i == n-1){
     71             for (int k=0;k<t;k++){
     72                 if (node[k].cnt>=2 && node[k].maxsa-node[k].minsa>=x){
     73                     tot++;
     74                 }
     75                 node[k].init();
     76             }
     77             if (tot == t){
     78                 return true;
     79             }
     80             tot = 0;
     81             break;
     82         }
     83         if (height[i]>=x){
     84             if (!vis[i]){
     85                 vis[i] = 1;
     86                 node[idx].cnt++;
     87                 node[idx].maxsa = max(sa[i],node[idx].maxsa);
     88                 node[idx].minsa = min(sa[i],node[idx].minsa);
     89             }
     90             if (!vis[i-1]){
     91                 vis[i-1] = 1;
     92                 node[lidx].cnt++;
     93                 node[lidx].maxsa = max(sa[i-1],node[lidx].maxsa);
     94                 node[lidx].minsa = min(sa[i-1],node[lidx].minsa);
     95             }
     96         }
     97         else{
     98             for (int k=0;k<t;k++){
     99                 if (node[k].cnt>=2 && node[k].maxsa-node[k].minsa>=x){
    100                     tot++;
    101                 }
    102                 node[k].init();
    103             }
    104             if (tot == t){
    105                 return true;
    106             }
    107             tot = 0;
    108         }
    109     }
    110     return false;
    111 }
    112 
    113 
    114 int main()
    115 {
    116     int T;
    117     scanf("%d",&T);
    118     while (T--) {
    119         scanf("%d",&t);
    120         int XX = 30;
    121         int n = 0;
    122         for (int i=0;i<t;i++){
    123             scanf("%s",s);
    124             int len = strlen(s);
    125             for (int j=0;j<len;j++){
    126                 r[n++] = s[j]-'a'+1;
    127                 indexx[n-1] = i;
    128             }
    129             indexx[n] = i;
    130             r[n++] = XX++;
    131         }
    132         r[n] = 0;
    133         Suffix(r,sa,n+1,128);
    134         calheight(r,sa,n);
    135         int L=1,R=10000,mid,len=0;
    136         while (L<=R){
    137             mid = (L+R)>>1;
    138             if (check(mid,n)){
    139                 len = mid;
    140                 L = mid+1;
    141             }else
    142                 R = mid-1;
    143         }
    144         printf("%d
    ",len);
    145     }
    146     return 0;
    147 }
  • 相关阅读:
    ViewPager
    SpringBoot入门
    SpringMVC拦截器
    QML布局概述(Qt Quick Layouts Overview)
    Ubuntu16.04软件安装错误处理(以安装ssh-server为例)
    VirtualBox实用网络设置
    Ubuntu安装cmake 3.9
    QML学习笔记
    Qt一些方便易用的小技巧
    Qt 4.8.5 + MinGW32 + Qt creater 安装
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/11343528.html
Copyright © 2011-2022 走看看