kmp变形,带通配符的kmp——华科校赛E 好题

Posted zsben991126

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kmp变形,带通配符的kmp——华科校赛E 好题相关的知识,希望对你有一定的参考价值。

https://blog.csdn.net/a302549450/article/details/80948741?tdsourcetag=s_pctim_aiomsg

上面是题解的链接。。,

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define PI acos(-1)
#define INF 0x3f3f3f3f
#define NUM 101000
#define debug false
#define ll long long
#define lowbit(x) ((-(x))&(x))
#define ffor(i,d,u) for(int i=(d);i<=(u);++i)
#define _ffor(i,u,d) for(int i=(u);i>=(d);--i)
#define mst(array,Num) memset(array,Num,sizeof(array))
const int p = 1e9+7;
int n,k,m,_next[NUM],a[NUM<<1],b[NUM],ori[NUM<<1],par[NUM],pos[12];
int ans=0;
template <typename T>
void read(T& x)
{
    x=0;
    char c;
    while((c=getchar())<0||c>9);
    do((x*=10)+=((int)(c-0)));while((c=getchar())>=0&&c<=9);
}
template <typename T>
void write(T x)
{
    int len=0;char c[21];
    if(x<0)putchar(-);
    x=abs(x);
    do{++len;c[len]=(char)((x%10)+0);}while(x/=10);
    _ffor(i,len,1)putchar(c[i]);
}
void build()
{
    mst(pos,-1);
    par[1]=-1;
    pos[b[1]]=1;
    ffor(i,2,m)
    {
        if(pos[b[i]]!=-1)
            par[i]=i-pos[b[i]];
        else
            par[i]=-1;
        pos[b[i]]=i;
    }
    mst(pos,-1);
    ori[1]=-1;
    pos[a[1]]=1;
    ffor(i,2,n)
    {
        if(pos[a[i]]!=-1&&i-pos[a[i]]<m)
            ori[i]=i-pos[a[i]];
        else
            ori[i]=-1;
        pos[a[i]]=i;
    }
}
int getnext(int x)
{
    int i;
    i=_next[x];
    while(i!=-1 && par[i+1]!=par[x+1] && par[i+1]!=-1 )i=_next[i];
    return i+1;
}
bool pd(int x,int y)
{ //母串的x和模式串的y相等 或者 模式串的y无前驱且(y前的长度比x前驱小) 
    return (ori[x]==par[y] || (par[y]==-1 && ((y-ori[x])<1)));
}
void kmp()
{
    _next[0]=-1;_next[1]=0;
    ffor(i,2,m)
        _next[i]=getnext(i-1);
    int i=0,j=0;
    while(j<n)
    {
        while(i<m&&j<n&&pd(j+1,i+1)){++i;++j;}
        if(i==m)++ans;
        if(j==n)break;
        while(i==m||(i!=-1&&!pd(j+1,i+1)))i=_next[i];
        if(i==-1)
        {
            ++i;
            ++j;
        }
    }
}
void AC()
{
    read(n),read(k);
    ffor(i,1,n)
        read(a[i]);
    read(m);
    ffor(i,1,m)
        read(b[i]);
    build();
    kmp();
    write(ans);
}
int main()
{
    AC();
    return 0;
}

 

以上是关于kmp变形,带通配符的kmp——华科校赛E 好题的主要内容,如果未能解决你的问题,请参考以下文章

Fire Air(华科校赛 网络赛)

poj2185 kmp求最小覆盖矩阵,好题!

HDU 5918 SequenceI (2016 CCPC长春站 KMP模版变形)

CSU - 1581 Clock Pictures (KMP的变形题,难想到)

KMP算法实践与简单分析

ACM 选手带你玩转 KMP 算法!