BZOJ3679

6 篇文章 0 订阅
6 篇文章 0 订阅

BZOJ3679

KMP的nxt满足 S[0,k]==S[ik+1,i] S [ 0 , k ] == S [ i − k + 1 , i ]
可是这题需要满足长度<=(len+1)/2
所以我们假设 nxt[i]>i n x t [ i ] − − − > i (向 i i <script type="math/tex" id="MathJax-Element-36">i</script>连边),这样得到了一棵“Fail树”
我们要不断往上跳,直到dep<=(len+1)/2
然后。。就过了。。复杂度我也证不来。。大概就是p每次无需从头跳吧。。反正O(能过)

#include<bits/stdc++.h>
#define gt() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++)
#define pt(ch) (Top<1000000?St[Top++]=ch:(fwrite(St,1,1000000,stdout),St[(Top=0)++]=ch))
#define LL long long
#define __R register
#define isletter(ch) (ch>='a'&&ch<='z')
using namespace std;
int Top;static char St[1000000],buf[1000000],*p1=buf,*p2=buf;
const int maxn=(1e6)+5,TT=(1e9)+7;
int T,nxt[maxn],dep[maxn],lst[maxn];char s[maxn];LL Ans;
int read(){
    int ret=0;char ch=gt();
    while(ch<'0'||ch>'9') ch=gt();
    while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=gt();
    return ret;
}
void write(LL x){if(x>9) write(x/10);pt(x%10+'0');}
int main(){
    T=read();
    while(T--){
        __R int n=0;
        char ch=gt();while(!isletter(ch)) ch=gt();while(isletter(ch)) s[n++]=ch,ch=gt();
        __R int j=0,k=-1,p=0;nxt[0]=-1,dep[0]=0,Ans=1;
        while(j<n) if(k==-1||s[j]==s[k]){
            dep[j]=dep[nxt[++j]=++k]+1;
            if(j>=n) break;
            while(p!=-1&&s[j]!=s[p]) p=nxt[p];p++;
            while((p<<1)>j+1) p=nxt[p];
            (Ans*=dep[p]+1)%=TT;
        }else k=nxt[k];
        write(Ans),pt('\n');
    }
    fwrite(St,1,Top,stdout);
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值