• BZOJ4032: [HEOI2015]最短不公共子串


    n<=2000的两个串,求四个问:

    (1) A的一个最短的子串,它不是B的子串
    (2) A的一个最短的子串,它不是B的子序列
    (3) A的一个最短的子序列,它不是B的子串
    (4) A的一个最短的子序列,它不是B的子序列
     
    一开始??????嗯要识别子串和子序列需要俩东西:序列自动机和后缀自动机。
    前两问:枚举A的起点直接在两个自动机里走即可。
    后两问:
    方法一:(x,y)表示A的序列自动机上第x位和B的后缀/序列自动机上第y位匹配上时的最短串。从两个根节点开始bfs一次即可。复杂度n*n*26,空间巨大。
    方法二:只留一个状态y,把x当作一种转移途径,从左到右枚举A串字符,使B的自动机上所有和当前字符相同的转移路径进行一次转移。复杂度n*n。
      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stdlib.h>
      4 #include<algorithm>
      5 //#include<iostream>
      6 using namespace std;
      7 
      8 int n,m;
      9 #define maxn 4011
     10 char a[maxn],b[maxn];
     11 
     12 struct seAM
     13 {
     14     int ch[maxn][26],pre[maxn],last[26];
     15     seAM() {pre[1]=0; for (int i=0;i<26;i++) last[i]=1;}
     16     int idx(char c) {return c-'a';}
     17     void insert(char c,int p)
     18     {
     19         int id=idx(c);p++;
     20         pre[p]=last[id];
     21         for (int i=0;i<26;i++)
     22             for (int j=last[i];j && !ch[j][id];j=pre[j]) ch[j][id]=p;
     23         last[id]=p;
     24     }
     25 }sb;
     26 
     27 struct SAM
     28 {
     29     struct Node
     30     {
     31         int ch[26],pre,pos;
     32         Node() {memset(ch,0,sizeof(ch)); pre=0;}
     33     }a[maxn];
     34     int size,last,root;
     35     SAM() {root=1; a[1].pos=0; size=1; last=1;}
     36     int idx(char c) {return c-'a';}
     37     void insert(char c,int p)
     38     {
     39         int id=idx(c),x=++size;
     40         a[x].pos=p;
     41         int y=last;
     42         for (;y && !a[y].ch[id];y=a[y].pre) a[y].ch[id]=x;
     43         last=x;
     44         if (!y) a[x].pre=root;
     45         else if (a[a[y].ch[id]].pos==a[y].pos+1) a[x].pre=a[y].ch[id];
     46         else
     47         {
     48             int z=a[y].ch[id],w=++size;
     49             a[w]=a[z]; a[w].pos=a[y].pos+1;
     50             a[z].pre=a[x].pre=w;
     51             for (;y && a[y].ch[id]==z;y=a[y].pre) a[y].ch[id]=w;
     52         }
     53     }
     54 }sam;
     55 
     56 int f[maxn];
     57 int main()
     58 {
     59     scanf("%s%s",a+1,b+1);n=strlen(a+1);m=strlen(b+1);
     60     for (int i=1;i<=m;i++) sb.insert(b[i],i),sam.insert(b[i],i);
     61     int ans;
     62     
     63     ans=n+1;
     64     for (int i=1;i<=n;i++)
     65     {
     66         int p=sam.root,j;
     67         for (j=i;p && j<=n;j++) p=sam.a[p].ch[a[j]-'a'];
     68         if (!p) ans=min(ans,j-i);
     69     }
     70     if (ans>n) puts("-1");else printf("%d
    ",ans);
     71     
     72     ans=n+1;
     73     for (int i=1;i<=n;i++)
     74     {
     75         int p=1,j;
     76         for (j=i;p && j<=n;j++) p=sb.ch[p][a[j]-'a'];
     77         if (!p) ans=min(ans,j-i);
     78     }
     79     if (ans>n) puts("-1");else printf("%d
    ",ans);
     80     
     81     ans=n+1;
     82     memset(f,0x3f,sizeof(f));
     83     f[1]=0;
     84     for (int i=1;i<=n;i++)
     85         for (int j=sam.size;j>=1;j--)
     86         {
     87             int tmp;if (!(tmp=sam.a[j].ch[a[i]-'a'])) ans=min(ans,f[j]+1);
     88             else f[tmp]=min(f[tmp],f[j]+1);
     89         }
     90     if (ans>n) puts("-1");else printf("%d
    ",ans);
     91     
     92     ans=n+1;
     93     memset(f,0x3f,sizeof(f));
     94     f[1]=0;
     95     for (int i=1;i<=n;i++)
     96         for (int j=m+1;j>=1;j--)
     97         {
     98             int tmp;if (!(tmp=sb.ch[j][a[i]-'a'])) ans=min(ans,f[j]+1);
     99             else f[tmp]=min(f[tmp],f[j]+1);
    100         }
    101     if (ans>n) puts("-1");else printf("%d
    ",ans);
    102     
    103     return 0;
    104 }
    View Code
  • 相关阅读:
    Java Leetcode 两数之和
    Springboot 实现前后分离的固定响应结构 {code,data,msg} 代码及想法
    Java 通过原子类 AtomicStampedReference 实现自旋锁
    【待整理】PC端
    【Python】自动发送邮件
    【Python】调用C/C++ SDK/SO动态库
    【Python】整个项目所需的依赖包列表打包/项目迁移
    【待整理】工具
    【数据库】+Navicat 过期/14天试用期满
    【待整理】【后端】
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8010500.html
Copyright © 2020-2023  润新知