ZOJ 3587 Marlon's String 擴充KMP

來源:互聯網
上載者:User

標籤:字串   擴充kmp   

連結:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3587

題意:給出兩個字串S和T,S,T<=100000.拿出S的兩個子串(可以重疊),將兩個子串聯接起來成為字串T的方法有多少種。

思路:用擴充KMP求出S的從每位開始的子串與T的公用首碼,再將兩個子串翻轉,再用擴充KMP求出S反的從每位開始的子串與T反的公用首碼。找出其中和為T子串長度的S公用首碼和S反的公用首碼的數量,相乘為結果。

代碼:

#include <algorithm>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <ctime>#include <ctype.h>#include <iostream>#include <map>#include <queue>#include <set>#include <stack>#include <string>#include <vector>#define eps 1e-8#define INF 0x7fffffff#define maxn 10005#define PI acos(-1.0)#define seed 31//131,1313typedef long long LL;typedef unsigned long long ULL;using namespace std;const int N = 101010;int next_a[N],extand_a[N],next_c[N],extand_c[N];void getnext(char *T,int *next,int *extand) // next[i]: 以第i位置開始的子串 與 T的公用首碼{    int i,length = strlen(T);    next[0] = length;    for(i = 0; i<length-1 && T[i]==T[i+1]; i++);    next[1] = i;    int a = 1;    for(int k = 2; k < length; k++)    {        int p = a+next[a]-1, L = next[k-a];        if( (k-1)+L >= p )        {            int j = (p-k+1)>0? (p-k+1) : 0;            while(k+j<length && T[k+j]==T[j]) j++;// 枚舉(p+1,length) 與(p-k+1,length) 區間比較            next[k] = j, a = k;        }        else next[k] = L;    }}void getextand(char *S,char *T,int *next,int *extand) //s是母串,t是模式串{    memset(next,0,sizeof(next));    getnext(T,next,extand);    int Slen = strlen(S), Tlen = strlen(T), a = 0;    int MinLen = Slen>Tlen?Tlen:Slen;    while(a<MinLen && S[a]==T[a]) a++;    extand[0] = a, a = 0;    for(int k = 1; k < Slen; k++)    {        int p = a+extand[a]-1, L = next[k-a];        if( (k-1)+L >= p )        {            int j = (p-k+1)>0? (p-k+1) : 0;            while(k+j<Slen && j<Tlen && S[k+j]==T[j] ) j++;            extand[k] = j;            a = k;        }        else extand[k] = L;    }}char a[100005],b[100005],c[100005],d[100005];LL t_a[100005],t_c[100005];void init(){    memset(t_a,0,sizeof(t_a));    memset(t_c,0,sizeof(t_c));}int main(){    //freopen("1.txt","r",stdin);    int T;    scanf("%d",&T);    while(T--)    {        init();        scanf("%s",a);        scanf("%s",b);        int len_a=strlen(a);        for(int i=0;i<len_a;i++)            c[i]=a[len_a-1-i];        c[len_a]='\0';        int len_b=strlen(b);        for(int i=0;i<len_b;i++)            d[i]=b[len_b-1-i];        d[len_b]='\0';        getextand(a,b,next_a,extand_a);        getextand(c,d,next_c,extand_c);        for(int i=0;i<len_a;i++)        {            t_a[extand_a[i]]++;            t_c[extand_c[i]]++;        }        for(int i=len_a-1;i>=1;i--)        {            t_a[i]+=t_a[i+1];            t_c[i]+=t_c[i+1];        }        LL ans=0;        for(int i=1;i<len_b;i++)        {            ans+=t_a[i]*t_c[len_b-i];        }        printf("%lld\n",ans);    }    return 0;}


ZOJ 3587 Marlon's String 擴充KMP

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.