zoukankan      html  css  js  c++  java
  • P2375 [NOI2014]动物园

    传送门

    如果不考虑不重叠的限制的话,$num[i]$ 是很容易求的:

    scanf("%s",s+1);
    int j=0; n=strlen(s+1); num[1]=1;
    for(int i=2;i<=n;i++)
    {
        while(j&&s[j+1]!=s[i]) j=f[j];
        f[i]= s[j+1]==s[i] ? ++j : 0;
        num[i]=num[j]+1;
    }

    对于限制,考虑每个点都暴力跳 $fail$,直到跳到合法为止

    for(int i=1,j=i;i<=n;i++,j=i)
    {while(j>i/2) j=f[j];
        ans=1ll*ans*(num[j]+1)%mo;
    }

    但是这种做法可以被卡到 $n^2$($aaaaaaaaaa...$ 这样的数据)

    考虑 $KMP$ 时怎么维护 $fail$ 的,搞一个指针 $j$,指向当前上一个位置的 $fail$,这样就不用每次都重新跳了

    那我们维护 $num$ 也可以考虑这种操作,然后复杂度就是 $O(n)$

    具体看代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    using namespace std;
    typedef long long ll;
    typedef double db;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int N=2e6+7,mo=1e9+7;
    int n,f[N],num[N],ans=1;
    char s[N];
    int main()
    {
        int T=read();
        while(T--)
        {
            scanf("%s",s+1);
            int j=0; n=strlen(s+1); ans=num[1]=1;
            for(int i=2;i<=n;i++)
            {
                while(j&&s[j+1]!=s[i]) j=f[j];
                f[i]= s[j+1]==s[i] ? ++j : 0;
                num[i]=num[j]+1;
            }
            j=0;
            for(int i=2;i<=n;i++)
            {
                while(j&&s[j+1]!=s[i]) j=f[j];
                if(s[j+1]==s[i]) j++;
                while(j>i/2) j=f[j];
                ans=1ll*ans*(num[j]+1)%mo;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    【HDOJ】5179 beautiful number
    【HDOJ】3459 Rubik 2×2×2
    【HDOJ】3419 The Three Groups
    【HDOJ】3085 Nightmare Ⅱ
    【HDOJ】3451 Beat drop
    【HDOJ】3309 Roll The Cube
    WP手机使用记录
    WinCE系统下应用崩溃原因的分析方法
    指针减法
    WinCE Overlay
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/11334536.html
Copyright © 2011-2022 走看看