bzoj 3670 [Noi2014]动物园

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3670

重点是记录一个cnt数组表示自己这个串能匹配几次。如果记录的是不包含自己第一次匹配上的那种(如代码),要注意判断。

学习到了优美写法。就是用两个全局变量的指针而不是每次都 int k=nxt[ i-1 ]。

  而且那个while写得也很好!这样就不用特别判断没匹配上的情况了。

注意输出换行。

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int N=1e6+5;
const ll mod=1e9+7;
int T,len,nxt[N],cnt[N],k,ct;
char a[N];
ll sum;
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        sum=1;k=ct=0;//
        memset(cnt,0,sizeof cnt);
        scanf("%s",a+1);len=strlen(a+1);
        for(int i=2;i<=len;i++)
        {
            ll nm=0;
            while(k&&a[k+1]!=a[i])k=nxt[k];
            if(a[k+1]==a[i])k++;
            nxt[i]=k;if(k)cnt[i]=cnt[k]+1;//if k
            
            while(ct&&a[ct+1]!=a[i])ct=nxt[ct];
            if(a[ct+1]==a[i])ct++;
            while(ct>(i>>1))ct=nxt[ct];//
            if(ct)nm=cnt[ct]+1;//if ct
            (sum*=nm+1)%=mod;
        }
        printf("%lld\n",sum);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Narh/p/9197078.html