TLE问题
查看原帖
TLE问题
270757
老徐楼主2021/2/17 15:18
// https://www.luogu.com.cn/problem/P2375

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>

using namespace std;
typedef long long ll;

const int maxn = 1e6 + 10;
ll kmp_next[maxn];
char str[maxn];
const ll mod = 1e9 + 7;
ll ans[maxn];

void getnext(char *str)
{
    kmp_next[1] = 0;
    ans[0] = 0;
    ans[1] = 1;// 可以重叠的公共前后缀 a = a
    int len = strlen(str);
    for (int i = 1, j = 0; i < len; i++)
    {
        while (j && (str[i] != str[j]))
            j = kmp_next[j];
        j += (str[i] == str[j]);
        kmp_next[i + 1] = j;
        // 记录可以重叠的公共前后缀数量ans
        // 包括自己本身 比如 abc为前缀 abc为后缀 
        // ans[3] = ans[0]+1 = 1
        ans[i + 1] = ans[j] + 1;
    }
}

int main()
{
    // freopen("in", "r", stdin);
    int n;
    scanf("%d", &n);

    while (n--)
    {
        scanf("%s", str);
        getnext(str);
        int len = strlen(str);
        int cnt = 1;

        for (int i = 1, j = 0; i < len; i++)
        {
            while (j && (str[i] != str[j]))
                j = kmp_next[j];
            j += (str[i] == str[j]); // 到这一步是算出最长的公共前后缀 也就是kmp_next

            // j = kmp_next[i+1]; // 所以可以直接这样赋值,但是这样复制会TLE???

            while ((j << 1) > (i + 1)) // j*2 > (i+1)
                j = kmp_next[j]; // 找到没有覆盖的
            cnt = (cnt * (ll)(ans[j] + 1)) % mod;
        }
        printf("%lld\n", cnt % mod);
    }
    return 0;
}

在第56行那里如果直接赋值 j = kmp_next[i+1];为什么会TLE

蒟蒻想了半天都没搞懂

2021/2/17 15:18
加载中...