zoukankan      html  css  js  c++  java
  • Bzoj3670: [Noi2014]动物园

    题面

    传送门

    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
    ", ans);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    程序是访问数据库的组件
    Mac搭建Vue
    Sharding-JDBC基本使用,整合Springboot实现分库分表,读写分离
    随意写写
    maven打包工具assembly打包本地jar的解决办法
    Go语言笔记 (2) 变量命名与多重赋值
    Go语言笔记(1)变量的定义与赋值
    c期末笔记(4)
    c期末笔记(3)
    c期末笔记(2)
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8309922.html
Copyright © 2011-2022 走看看