zoukankan      html  css  js  c++  java
  • Codeforces Round #244 (Div. 2) D. Match & Catch(后缀自动机裸题)

    题目链接:Codeforces Round #244 (Div. 2) D. Match & Catch

    题意:

    给你两个串A,B,问你是否存在一个串x,使得x是A,B的子串,并且只在A,B中出现一次。

    题解:

    对于两个串分别建立后缀自动机,更新一下right集,然后dfs一下,更新一下答案就行了。

     1 #include<bits/stdc++.h>
     2 #define mst(a,b) memset(a,b,sizeof(a))
     3 #define F(i,a,b) for(int i=(a);i<=(b);++i)
     4 using namespace std;
     5 
     6 const int N=5e3+7,tyn=26,M=N*2;
     7 struct SAM{
     8     int tr[M][tyn],f[M],ml[M],ed,last,p,x,r,q;
     9     int cnt[M],b[M],d[M];
    10     inline int gid(char x){return x-'a';}
    11     inline void nc(int s,int &p){
    12         ml[p=++ed]=s,f[ed]=cnt[ed]=0,mst(tr[ed],0);
    13     }
    14     void clear(){ed=0,nc(0,last);}
    15     void add(int w){
    16         nc(ml[x=last]+1,p),last=p,cnt[p]=1;
    17         while(x&&!tr[x][w])tr[x][w]=p,x=f[x];
    18         if(!x)f[p]=1;
    19         else if(ml[x]+1==ml[q=tr[x][w]])f[p]=q;
    20         else{
    21             nc(ml[x]+1,r),f[r]=f[q],f[p]=f[q]=r;
    22             memcpy(tr[r],tr[q],sizeof(tr[r]));
    23             while(x&&tr[x][w]==q)tr[x][w]=r,x=f[x];
    24         }
    25     }
    26     void upright(int mx=0){
    27         F(i,0,ed)d[i]=0;
    28         F(i,1,ed)d[mx<ml[i]?mx=ml[i]:ml[i]]++;
    29         F(i,1,mx)d[i]+=d[i-1];
    30         F(i,1,ed)b[d[ml[i]]--]=i;
    31         for(int i=ed;i;--i)cnt[f[b[i]]]+=cnt[b[i]];
    32     }//从1开始
    33     void build(char *s){for(int i=1;s[i];i++)add(gid(s[i]));}
    34 }sam[2];
    35 
    36 char s[N];
    37 int ans=INT_MAX;
    38 
    39 void go(int x,int y,int len)
    40 {
    41     if(len>ans)return;
    42     if(len&&sam[0].cnt[x]==1&&sam[1].cnt[y]==1)
    43     {
    44         ans=min(ans,len);
    45         return;
    46     }
    47     F(i,0,25)if(sam[0].tr[x][i]&&sam[1].tr[y][i])
    48         go(sam[0].tr[x][i],sam[1].tr[y][i],len+1);
    49 }
    50 
    51 int main(){
    52     scanf("%s",s+1);
    53     sam[0].clear(),sam[0].build(s),sam[0].upright();
    54     scanf("%s",s+1);
    55     sam[1].clear(),sam[1].build(s),sam[1].upright();
    56     go(1,1,0);
    57     printf("%d
    ",ans==INT_MAX?-1:ans);
    58     return 0;
    59 }
    View Code
  • 相关阅读:
    鸡兔同笼问题多解
    JavaSE复习日记 : 循环语句(for/while/do while)
    JavaSE复习日记 : 八种基本数据类型
    递归函数
    JavaSE复习日记 : 条件判断语句
    访问权限系列一(public/private/protected/default):成员变量
    JavaSE复习日记 : 算是个小前言吧
    转:SQL Server 索引和视图
    转:SQL Server 数据库基础编程
    转:在网页html/aspx中增加一段播放器代码
  • 原文地址:https://www.cnblogs.com/bin-gege/p/7588565.html
Copyright © 2011-2022 走看看