Luogu 2375 [NOI2014]动物园
字胡串什么的一直不太会,感觉这题…还蛮本质的
考虑暴力求解:num[i]相当于从一直跳nxt,如果nxt[j] * 2 <= i 那么就累加答案
其实这是一个树的结构,也就是说跳到一个结点满足条件,那么它上面的结点一定都满足,所以在求nxt的时候顺便递推一下每一个结点的答案,那么模拟一下匹配nxt的过程,只要跳到第一个j * 2 <= i 就可以算答案了
不会算时间复杂度QuQ
Code:
#include <cstdio> #include <cstring> using namespace std; typedef long long ll; const int N = 1e6 + 5; const ll mod = 1e9 + 7; int testCase, n, nxt[N]; ll num[N]; char s[N]; int main() { for(scanf("%d", &testCase); testCase--; ) { scanf("%s", s + 1); n = strlen(s + 1); memset(nxt, 0, sizeof(nxt)); memset(num, 0, sizeof(num)); num[1] = 1; for(int i = 2, j = 0; i <= n; i++) { for(; j > 0 && s[j + 1] != s[i]; j = nxt[j]); if(s[j + 1] == s[i]) j++; nxt[i] = j; num[i] = num[j] + 1LL; } ll ans = 1LL; for(int i = 2, j = 0; i <= n; i++) { for(; j > 0 && s[j + 1] != s[i]; j = nxt[j]); if(s[j + 1] == s[i]) j++; for(; (j * 2) > i; j = nxt[j]); ans = ans * (num[j] + 1)% mod; } printf("%lld\n", ans); } return 0; }