1. 程式人生 > >【字串】【KMP】BZOJ3670動物園

【字串】【KMP】BZOJ3670動物園

分析:

不算太難的fail指標應用題。每次利用fail指標在上一個位置的匹配資訊,不停地向下匹配,如果超過一半則退回去即可。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#define SF scanf
#define PF printf
#define MAXN 1000010
#define MOD 1000000007
using namespace std;
typedef long long ll;
int n;
char s[MAXN]
; int fail[MAXN],dep[MAXN]; ll ans; void build(){ int las=-1; fail[0]=-1; for(int i=0;i<n;i++){ while(las!=-1&&s[las]!=s[i]) las=fail[las]; fail[i+1]=las+1; dep[i+1]=dep[fail[i+1]]+1; //PF("[%d %d %d]\n",i+1,fail[i+1],dep[i+1]); las++; } } void solve(){ int las=-1; for(int i=
0;i<n;i++){ while(las!=-1&&s[i]!=s[las]) las=fail[las]; las++; while(las!=-1&&(las<<1)>i+1) las=fail[las]; //PF("---[%d %lld %lld]---\n",las,ans,dep[las]+1ll); if(las!=-1) ans=ans*1ll*(dep[las]+1)%MOD; } } int main(){ int t; SF("%d",&t); while(t--)
{ SF("%s",s); n=strlen(s); memset(fail,0,sizeof fail); memset(dep,0,sizeof dep); build(); ans=1; solve(); PF("%lld\n",ans); } }