码迷,mamicode.com
首页 > 其他好文 > 详细

Bzoj3670: [Noi2014]动物园

时间:2018-01-18 15:00:42      阅读:122      评论:0      收藏:0      [点我收藏+]

标签:online   长度   size   href   getc   typedef   strlen   理解   mat   

题面

传送门

Sol

这是一道阅读理解题,读了好久才明白意思。。。
首先可以想到处理出next数组,每次的位置i跳next跳到长度小于i的一半位置,然后继续跳到零统计此时跳的次数就是答案
那么暴力就是\(O(n^2)\)
让我们一起膜拜yyb大佬的倍增跳next

那么优化就是在求next的时候再开一个指针,每次强制跳到i的一半的位置。。。
再开数组cnt,每次由next指针的位置的cnt+1转移而来,然后就没了

# include <bits/stdc++.h>
# define RG register
# define IL inline
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
const int _(1e6 + 1), Zsy(1e9 + 7);

IL ll Read(){
    RG ll x = 0, z = 1; RG char c = getchar();
    for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
    for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
    return x * z;
}

int l, ans, nxt[_], cnt[_];
char s[_];

int main(RG int argc, RG char* argv[]){
    for(RG int T = Read(); T; --T){
        scanf(" %s", s + 1); cnt[1] = ans = 1; l = strlen(s + 1);
        for(RG int i = 2; i <= l; ++i) nxt[i] = cnt[i] = 0;
        for(RG int i = 2, j = 0, k = 0; i <= l; ++i){
            while(j && s[i] != s[j + 1]) j = nxt[j];
            if(s[i] == s[j + 1]) nxt[i] = ++j;
            cnt[i] = cnt[j] + 1;
            while(k && s[i] != s[k + 1]) k = nxt[k];
            if(s[i] == s[k + 1]) ++k;
            while((k << 1) > i) k = nxt[k];
            ans = 1LL * ans * (cnt[k] + 1) % Zsy;
        }
        printf("%d\n", ans);
    }
    return 0;
}

Bzoj3670: [Noi2014]动物园

标签:online   长度   size   href   getc   typedef   strlen   理解   mat   

原文地址:https://www.cnblogs.com/cjoieryl/p/8309922.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!