扩展 KMP(模板) 洛谷P5410

题目:https://www.luogu.org/problemnew/show/P5410

https://www.luogu.org/blog/lc-2018-Canton/solution-p5410

  

#include<bits/stdc++.h>

using namespace std;

#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f

const int maxn=1e5+10;

int nxt[maxn],extend[maxn];

int q;

string s,t;


void getnxt()
{
    int l=t.size();
    nxt[0]=l;
    int now=0;
    while(t[now]==t[now+1]&&now+1<l) now++;
    nxt[1]=now;
    int p0=1;//可以到达最远位置的i
    for(int i=2;i<l;i++)
    {
        if(i+nxt[i-p0]<nxt[p0]+p0)
            nxt[i]=nxt[i-p0];
        else
        {
            int now=nxt[p0]+p0-i;
            now=max(now,0);//这里是为了防止i>p的情况
            while(t[now]==t[i+now]&&i+now<l)
                now++;
            nxt[i]=now;
            p0=i;
        }
    }
}

void exkmp()
{
    getnxt();
    int now=0;
    int lim=min(s.size(),t.size());
    int l=s.size();
    int l1=t.size();
    while(s[now]==t[now]&&now<lim)
        now++;
    extend[0]=now;
    int p0=0;
    for(int i=1;i<l;i++)
    {
        if(i+nxt[i-p0]<extend[p0]+p0)
            extend[i]=nxt[i-p0];
        else
        {
            int now=extend[p0]+p0-i;
            now=max(now,0);
            while(t[now]==s[i+now]&&now<l1&&now+i<l)
                now++;
            extend[i]=now;
            p0=i;
        }
    }
}

int main()
{
    cin>>s>>t;
    exkmp();
    int l=t.size(),l1=s.size();
    for(int i=0;i<l;i++)
    {
        cout<<nxt[i]<<" ";
    }cout<<endl;
    for(int i=0;i<l1;i++)
    {
        cout<<extend[i]<<" ";
    }cout<<endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/minun/p/11041988.html
今日推荐