P2375 [NOI2014] 动物园
P2375 [NOI2014] 动物园
题意是对于每个前缀,求前缀后缀不交的且前后缀相等的前后缀数量数组,。
考虑先求出正常的 数组,KMP 求解。
对于 数组,可以由前一个数的 数组转移,如果新数大小超过了 就跳到前一个 数组。因为如果现在已经超出长度限制,加 后一定超出,所以这么做是正确的。
记录 只需要在过程中递推一下就好了。详见代码。
时间复杂度 。
#include<bits/stdc++.h> // #define LOCAL #define sf scanf #define pf printf #define rep(x,y,z) for(int x=y;x<=z;x++) using namespace std; typedef long long ll; const int N = 1e6 + 7, mod = 1e9 + 7; ll ans; int n,l; char c[N]; int nex[N],num[N]; void getans () { num[1] = 1; int j = 0; rep(i, 1, l - 1) { while(j && c[i] != c[j]) j = nex[j]; if(c[i] == c[j]) j++; nex[i + 1] = j; num[i + 1] = num[j] + 1; } j = 0; rep(i, 1, l - 1) { while(j && (c[i] != c[j])) j = nex[j]; if(c[i] == c[j]) j++; while((j<<1) > (i + 1) ) j = nex[j]; ans = ans * (num[j] + 1) % mod; } } int main () { #ifdef LOCAL freopen("in.txt", "r", stdin); freopen("my.out", "w", stdout); #endif sf("%d" , &n ); while (n--) { memset(nex, 0, sizeof(nex)); memset(num, 0, sizeof(num)); ans = 1; sf("%s", c); l = strlen(c); getans(); pf("%lld\n", ans); } }
本文来自博客园,作者:wing_heart,转载请注明原文链接:https://www.cnblogs.com/wingheart/p/18435496
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现