zoukankan      html  css  js  c++  java
  • bzoj3796: Mushroom追妹纸

    Description

    Mushroom最近看上了一个漂亮妹纸。他选择一种非常经典的手段来表达自己的心意——写情书。考虑到自己的表达能力,Mushroom决定不手写情书。他从网上找到了两篇极佳的情书,打算选择其中共同的部分。另外,Mushroom还有个一个情敌Ertanis,此人也写了封情书给妹子。
    Mushroom不希望自己的情书中完整的出现了情敌的情书。(这样抄袭的事情就暴露了)。
    Mushroom把两封情书分别用字符串s1和s2来表示,Ertanis的情书用字符串s3来表示,他要截取的部分用字符串w表示。
    需满足:
    1、w是s1的子串
    2、w是s2的子串
    3、s3不是w的子串
    4、w的长度应尽可能大
    所谓子串是指:在字符串中连续的一段
    【输入】
    输入文件为girl.in
    输入有三行,第一行为一个字符串s1第二行为一个字符串s2, 
    第三行为一个字符串s3。输入仅含小写字母,字符中间不含空格。
    【输出】
    输出文件为girl.out
    输出仅有一行,为w的最大可能长度,如w不存在,则输出0。
    【输入样例】
    abcdef
    abcf
    bc
    【输出样例】
    2
    【样例解释】
    s1和s2的公共子串有abc,ab,bc,a,b,c,f,其中abc,bc包含子串bc不合法,所以最长的合法子串为ab。
    【数据规模】
    对于30%的数据:1<=s1、s2、s3的长度<=500
    对于60%的数据:1<=s1、s2、s3的长度<=5000
    对于100%的数据:1<=s1、s2的长度<=50000,1<=s3的长度<=10000
     

    Input

    输入有三行,第一行为一个字符串s1第二行为一个字符串s2, 
    第三行为一个字符串s3。输入仅含小写字母,字符中间不含空格。

    Output

    输出仅有一行,为w的最大可能长度,如w不存在,则输出0。

    Sample Input

    abcdef
    abcf
    bc

    Sample Output

    2
    【样例解释】
    s1和s2的公共子串有abc,ab,bc,a,b,c,f,其中abc,bc包含子串bc不合法,所以最长的合法子串为ab。

    HINT

    对于100%的数据:1<=s1、s2的长度<=50000,1<=s3的长度<=10000

     

    先把串S1和串S2拼接成串S(中间用’#’隔开),然后求一下height。

    再对于S串每个后缀i,求出f[i]表示该串不包含S3串的最长前缀

    然后就在一般的求最长公共子串的基础上把ans=max(ans,height[i])改成ans=max(ans,min(height[i],min(f[SA[i-1]],f[SA[i]])))就行了

    code:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #define maxn 100005
     7 #define maxl 10005
     8 using namespace std;
     9 char s[maxn],s1[maxn],s2[maxn],s3[maxn];
    10 int n,m,l1,l2,tot,SA[maxn],height[maxn],rank[maxn],t1[maxn],t2[maxn],sum[maxn];
    11 int cnt,ans,pre[maxn],list[maxn],f[maxn];
    12 bool bo[maxn];
    13 void get_SA(){
    14     int *x=t1,*y=t2;
    15     for (int i=1;i<=n;i++) sum[x[i]=s[i]]++;
    16     for (int i=1;i<=m;i++) sum[i]+=sum[i-1];
    17     for (int i=n;i>=1;i--) SA[sum[x[i]]--]=i;
    18     tot=0;
    19     for (int len=1;tot<n;len<<=1,m=tot){
    20         tot=0;
    21         for (int i=n-len+1;i<=n;i++) y[++tot]=i;
    22         for (int i=1;i<=n;i++) if (SA[i]>len) y[++tot]=SA[i]-len;
    23         for (int i=1;i<=m;i++) sum[i]=0;
    24         for (int i=1;i<=n;i++) sum[x[y[i]]]++;
    25         for (int i=1;i<=m;i++) sum[i]+=sum[i-1];
    26         for (int i=n;i>=1;i--) SA[sum[x[y[i]]]--]=y[i];
    27         swap(x,y),x[SA[1]]=tot=1;
    28         for (int i=2;i<=n;i++){
    29             if (y[SA[i]]!=y[SA[i-1]]||y[SA[i]+len]!=y[SA[i-1]+len]) tot++;
    30             x[SA[i]]=tot;    
    31         }
    32     }
    33     for (int i=1;i<=n;i++) rank[i]=x[i];
    34 }
    35 void get_height(){
    36     for (int i=1,j=0;i<=n;i++){
    37         if (rank[i]==1) continue;
    38         while (s[i+j]==s[SA[rank[i]-1]+j]) j++;
    39         height[rank[i]]=j;
    40         if (j) j--;
    41     }    
    42 }
    43 void prepare(){
    44     l2=strlen(s3+1)+1,s3[l2]='$';
    45     for (int i=2,j=0;i<=l2;i++){
    46         while (j&&s3[i]!=s3[j+1]) j=pre[j];
    47         if (s3[i]==s3[j+1]) j++;
    48         pre[i]=j;
    49     }
    50     for (int i=1,j=0;i<=n;i++){
    51         while (j&&s[i]!=s3[j+1]) j=pre[j];
    52         if (s[i]==s3[j+1]) j++;
    53         if (j==l2-1) list[++cnt]=i-l2+2;
    54     }
    55     for (int i=1,j=1;i<=n;i++){
    56         while (j<=cnt&&list[j]<i) j++;
    57         if (j>cnt) f[i]=n-i+1;
    58         else f[i]=list[j]-i+l2-2;
    59     }
    60 }
    61 int main(){
    62     scanf("%s",s1+1),scanf("%s",s2+1),scanf("%s",s3+1);
    63     for (int i=1;s1[i];i++) n++,s[i]=s1[i];
    64     l1=strlen(s1+1)+1,s[l1]='#',n++;
    65     for (int i=1;s2[i];i++) n++,s[l1+i]=s2[i];
    66     m=123,get_SA(),get_height();
    67     prepare();
    68     for (int i=2;i<=n;i++)
    69         if ((SA[i-1]<l1&&SA[i]>l1)||(SA[i-1]>l1&&SA[i]<l1)) 
    70             ans=max(ans,min(height[i],min(f[SA[i-1]],f[SA[i]])));
    71     printf("%d
    ",ans);
    72     return 0;
    73 }
  • 相关阅读:
    题解[LuoguP7419 「PMOI-2」参天大树]
    UVA11582 巨大的斐波那契数! Colossal Fibonacci Numbers!
    数学专题
    [计蒜客]dp
    [蓝桥杯每日一题]1.3 & 1.4
    【acm】2020icpc南京补题
    [acm]乐师师范学院校赛题解-2020
    西南交通大学峨眉校区第二届"INT"杯程序设计竞赛——决赛
    指针与结构体
    [acm] 动态规划——最长上升子序列
  • 原文地址:https://www.cnblogs.com/chenyushuo/p/4694087.html
Copyright © 2011-2022 走看看