P2375 [NOI2014] KMP zoo

Well, the violence could get $ 50pts \ space qwq $


 

Violence idea is to keep hopping $ nxt [j] $, until it is less than half the length of the string, and then starts counting, of course, then jump to $ nxt [j] $

Positive Solutions: considering not required length (not required does not overlap) the number of common prefix and suffix, apparently $ ans [i] = ans [j] + 1 $ corresponds to $ I $ than $ J $ is more than $ I $ itself .

Therefore to imitate $ KMP $ during the solution process, $ num [i] $ is to keep hopping $ nxt [j] $, then until the $ j <= \ frac {i} {2} $, $ num [i] = ans [ j] $

Note that mimic $ kmp $ reason here is to avoid skipping some redundancy of $ nxt [j] $ ($ nxt [j] $ is too large), for the next match, the last of the $ j $ the last time that is less than equal to $ \ frac {i} {2} $ length of the longest common prefix and suffix, and if you can match directly match the long jump at $ nxt [j] $, otherwise it has been dancing $ nxt [j] $, until a match.

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define ull unsigned long long
#define ll long long
#define R register int
#define pause for(R i=1;i<=10000000000;++i)
using namespace std;
namespace Fread {
    static char B[1<<15],*S=B,*D=B;
    #define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++)
    inline int g() {
        R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
        do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
    } inline bool isempty(const char& ch) {return ch<=36||ch>=127;}
    inline void gs(char* s) {register char ch; while(isempty(ch=getchar())); do *s++=ch; while(!isempty(ch=getchar()));}
}using Fread::g; using Fread::gs;
const int M=1000000007;
int n,nxt[1000010],ans[1000010]; char s[1000010]; ll num=1;
inline void PRE() { nxt[1]=0;
    for(R i=2,j=0;i<=n;++i) { 
        while(j&&s[i]!=s[j+1]) j=nxt[j];
        if(s[i]==s[j+1]) ++j; nxt[i]=j;
        years [i] = years [j] + 1 ;
    }
}
inline void calc() {
    for(R i=2,j=0;i<=n;++i) {
        while(j&&s[i]!=s[j+1]) j=nxt[j];
        if(s[i]==s[j+1]) ++j; 
        while(j>i/2) j=nxt[j];
        (num * = (years [j] + 1 ))% = M;
    }
}
signed main() {
#ifdef JACK
    freopen("NOIPAK++.in","r",stdin);
#endif
    R t=g(); for(R i=1;i<=t;++i) { memset(s,0,sizeof(s)); num=1;
        gs(s+1); n=strlen(s+1);  ans[1]=1; PRE();
//        for(R i=2;i<=n;++i) { R lim=i/2,j=i,cnt=0;
//            while(j) {j=nxt[j]; if(j&&j<=lim) ++cnt;}
//            (ans*=(cnt+1))%=M; 
//        } 
        calc();
        printf("%lld\n",num);
    } 
}

2019.06.15

 

Guess you like

Origin www.cnblogs.com/Jackpei/p/11028492.html