求问 Z 函数

P2375 [NOI2014] 动物园

@[The_cosmos](/user/526017) ```cpp for(int i = 1; i < m; i ++) if(i <= min(i + Z[i] - 1, 2ll * (i - 1))) num[i] ++, num[min(i + Z[i] - 1, 2ll * (i - 1)) + 1] --; ``` 这一行有问题,该条件等价于 ```Z[i] >= 1 && i >= 2``` 而关键出在后面那个条件,即 $i = 1 $ 是可能满足的,而 ```num[min(i + Z[i] - 1, 2ll * (i - 1)) + 1]``` 也有问题,每个加个1就行了 改前: ``` 5 4 3 2 1 1 2 1 2 -1 12 2 0 1 1 1 8 0 0 2 0 3 0 0 1 1 1 2 0 2 1 0 8 ``` 改后: ``` 5 4 3 2 1 1 2 1 2 1 36 2 0 1 1 1 8 0 0 2 0 3 0 0 1 1 1 2 1 1 1 1 32 ``` 每组数据第一行为Z,第二行为num,你可以在比较一下
by XiaoYiii @ 2024-02-04 08:24:57


@[The_cosmos](/user/526017) 不过我似乎试不出 ```12 1 32``` 可能是我将您代码改成多组数据时改动了一下,附上改了第二个,没改第一个时的情况 ``` 5 4 3 2 1 1 1 2 2 1 18 2 0 1 1 1 8 0 0 2 0 3 0 0 1 1 1 2 1 1 1 1 32 ```
by XiaoYiii @ 2024-02-04 08:29:08


拜谢/bx
by The_cosmos @ 2024-02-04 08:29:21


@[The_cosmos](/user/526017) [ac](https://www.luogu.com.cn/record/146033781) 可以了 以下代码实在调不出来可以借鉴一下? ```cpp #include<bits/stdc++.h> using namespace std; const int N = 1e6 + 4; const long long int P = (1e9 + 7) * 1ll; int n; int main(){ scanf("%d", &n); while(n--){ int Z[N]; long long num[N]; string b; long long ans = 1; memset(Z, 0, sizeof Z), memset(num, 0, sizeof num); cin >> b; int m = b.size(); Z[0] = m; for (int i = 1, l = 0, r = 0; i < m; i ++) { if (i <= r) { Z[i] = min(Z[i - l], r - i + 1); } while (i + Z[i] < m && b[Z[i]] == b[i + Z[i]]) { Z[i] ++; } if (i + Z[i] - 1 > r) { r = i + Z[i] - 1; l = i; } } for(int i = 1; i < m; i ++){ if(Z[i]) { num[i]++; num[min(i + Z[i], 2 * i)] --; } } ans = num[0] + 1; for(int i = 1; i < m; i ++) {num[i] += num[i - 1], (ans *= (num[i] + 1)) %= P;} if(n) printf("%lld\n", ans); else printf("%lld", ans); } return 0; } ```
by XiaoYiii @ 2024-02-04 08:34:05


谢谢您/kk 过了。
by The_cosmos @ 2024-02-04 08:40:22


|