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

    [NOI2014] 动物园

    link

    试题分析

    首先一定与kmp数组有关。
    然后求出每个位置最长的题目要求的数组num。
    然后考虑这两个数组怎么统计。
    由于num前缀与后缀一样,那么只需要统计前i个的前缀等于后缀无要求的数量。
    这个东西我们可以直接从前后缀递推出来。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<algorithm>
     
    using namespace std;
    #define LL long long
     
    inline int read(){
        int x=0,f=1; char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int INF = 2147483600;
    const int MAXN = 2000010;
    const LL Mod = 1000000007;
     
    int nxt[MAXN+1],cnt[MAXN+1],num[MAXN+1];
    char str[MAXN+1]; int T;
     
    int main(){
        //freopen(".in","r",stdin);
        //freopen(".out","w",stdout);
        T=read();
        while(T--){
            memset(num,0,sizeof(num));
            memset(nxt,0,sizeof(nxt)); nxt[0]=-1; num[0]=-1;
            LL ans=1;
            scanf("%s",str+1); int len=strlen(str+1);
            for(int i=1;i<=len;i++){
                int j=i-1,k=i-1; while(j>-1){
                    if(str[i]==str[nxt[j]+1]) {nxt[i]=nxt[j]+1; break;}
                    else j=nxt[j];
                } cnt[i]=cnt[nxt[i]]+1;
                while(k>-1){
                    if(str[i]==str[num[k]+1]) {num[i]=num[k]+1; break;}
                    else k=num[k];
                } while(num[i]>(i>>1)) num[i]=nxt[num[i]];
                ans=1LL*ans*(cnt[num[i]]+1)%Mod;
            } printf("%lld
    ",ans);
        }
        return 0;
    }
    
    
  • 相关阅读:
    kafka环境搭建
    zookeeper环境搭建学习
    linux时间不准
    (转)Mac osx 下安装iTerm2,并使用rz sz上传下载(附homebrew配置)
    安装mariadb数据库
    mydumper 安装使用
    granfa 安装,配置prometheus数据源
    prometheus 普罗米修斯安装
    Docker常用命令
    winform 一个点击事件触发另一个点击事件
  • 原文地址:https://www.cnblogs.com/wxjor/p/9515898.html
Copyright © 2011-2022 走看看