【NOI2014】动物园 kmp
来源:互联网 发布:阿里云cdn怎么收费 编辑:程序博客网 时间:2024/05/16 00:16
题目链接: http://uoj.ac/problem/5
题意: 中文题目
解法:
如果num数组记载的前后缀允许重叠,是可以在递推next数组时顺路O(L)求出来的,这一步还算比较简单。
重点在于如何通过这个允许重叠的num数组求出不允许重叠时对应的num值。方法是让整个串再自己匹配自己一次,不过每次匹配时,如果j+1>(i+1)/2,即发现有重叠时,也要沿着next走。如果匹配成功,即str[i]==str[j],则说明i的num值应该是num[j]的值(因为也是这样递推算过来的),相乘即可;若匹配不成功,说明此时i的num值为0,答案要乘上1所以可以忽略。
//NOIP 2014#include <bits/stdc++.h>using namespace std;const int maxn = 1000010;const int mod = 1000000007;char s[maxn];int fail[maxn], nxt[maxn];long long ans;int main(){ int t; scanf("%d", &t); while(t--){ ans = 1; scanf("%s", s+1); int len = strlen(s+1); int j = 0; memset(fail, 0, sizeof(fail)); memset(nxt, 0, sizeof(nxt)); nxt[1] = 1; for(int i = 2; i <= len; i++){ while(s[j+1] != s[i] && j > 0) j = fail[j]; if(s[j+1] == s[i]) j++; fail[i] = j; nxt[i] = nxt[j]+1; } j = 0; for(int i = 2; i <= len; i++){ while(s[j+1]!=s[i]&&j>0) j = fail[j]; if(s[j+1]==s[i]) j++; while((j<<1)>i&&j>0) j = fail[j]; ans = (ans*(nxt[j]+1))%mod; } printf("%lld\n", ans); } return 0;}
0 0
- bzoj3670: [Noi2014]动物园 KMP
- 【KMP】[Noi2014] bzoj3670 动物园
- [BZOJ3670][Noi2014]动物园 && KMP
- [BZOJ3670]NOI2014动物园|KMP
- bzoj3670 [Noi2014]动物园 kmp
- 【bzoj3670】[Noi2014]动物园 KMP
- bzoj3670 NOI2014 动物园 kmp
- 【NOI2014】动物园 kmp
- BZOJ3670(Noi2014)[动物园]--KMP
- 【bzoj3670】【NOI2014】【动物园】【kmp+dp】
- 【 bzoj 3670 】 [Noi2014]动物园 - KMP
- bzoj 3670: [Noi2014]动物园 KMP
- BZOJ_P3670 [NOI2014]动物园(字符串+KMP)
- bzoj3670 noi2014动物园(kmp)
- [BZOJ3670][Noi2014]动物园(KMP)
- BZOJ 3670 [Noi2014] 动物园 KMP
- 【BZOJ】3670 [Noi2014]动物园 KMP
- [UOJ 5]【NOI2014】动物园:KMP
- 快速排序
- Log4j2 配置笔记(Eclipse+maven+SpringMVC)
- IOS---判断字符串是否为空
- MyBatis Dao插入数据的实现
- 大型网站的架构模式
- 【NOI2014】动物园 kmp
- 解密ThreadLocal
- 带你飞过PMP—备考上篇•乖乖看书就对了-GZ1610吴慧敏
- Android中为什么主线程不会因为Looper.loop()里的死循环卡死?
- android6.0系统Healthd深入分析
- 关于EOF的几个问题
- HDU 5550 Game Rooms (dp)
- HTML+CSS学习路线
- centos7 安装 mariadb(mysq的一种) 的正确命令