初试KMP!

来源:互联网 发布:java小数点保留两位 编辑:程序博客网 时间:2024/06/12 21:42

题目链接

题意:一堆废话,就是说取一个前缀和一个后缀,求他们之间相同的字串的长度(然后按题意算一算)。

难点就是求这个相同的长度。

当然首想KMP;(KMP的next数组存的是前面字串前缀和后缀重复的长度)

枚举每一个后缀,再枚举每一个前缀,求一下公共长度,算一下就好了!

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#include<iostream>#include<algorithm>#include<stack>#include<queue>#include<vector>#include<set>#include<map>#include<string>using namespace std;typedef long long ll;const int INF=0x3f3f3f3f;char str[2010],*s;int nextt[2010];ll ans;int len,len2;void get_next(){    nextt[0]=-1;    int i=0,j=-1;    while(i<len2)    {        if(j==-1||s[i]==s[j])        {            i++,j++;            if(s[i]!=s[j]) nextt[i]=j;            else nextt[i]=nextt[j];        }        else            j=nextt[j];    }}int main(){    int t;    scanf("%d",&t);    while(t--)    {        ans=0;        scanf("%s",str);        len=strlen(str);        for(int i=len-1;i>=0;i--)        {            s=&str[i];            len2=len-i;            get_next();            int k=0;            for(int j=0;j<len;j++)            {                   while(k&&str[j]!=s[k])                    k=nextt[k];                if(str[j]==s[k])                    k++;                else                    k=0;                ans^=1ll*k*k*(j-k+1)*(len2-k);            }        }        printf("%lld\n",ans);    }    return 0;}