TLE on #6 求卡常
查看原帖
TLE on #6 求卡常
755337
crimson000楼主2023/5/19 18:08

rt,本地测试250x250的全a方阵可以在0.7s跑出结果但是CF直接TLE

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> PII;

inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = (x << 3) + (x << 1) + ch - '0';
        ch = getchar();
    }
    return x * f;
}

const int N = 510, M1 = 20080113, M2 = 20070912, P = 13331, mod = 998244353;
char a[N][N];
ll Hash[N][N];
ll t[N], s[N << 2];
bool ok[N];
int f[N << 2];
ll p[N]; 
int cnt[N][N][26], idx;
ll ans;
int n, m, len;
inline int add(int x,int y)
{
    if(x+y>mod) return x+y-mod;
    return x+y;
}
inline ll gethash(int k, int l, int r)
{
    int cntt = 0;
    ll res = 0;
    for(register int i = 0; i < 26; i ++ )
    {
        int cnti = cnt[k][r][i] - cnt[k][l - 1][i];
        if(cnti & 1) cntt ++;
        res = add(res * P%mod,cnti);
    }
    if(cntt <= 1) ok[k] = true;
    return res;
}

inline void init()
{
    len = 0;
    s[++ len] = M1;
    for(register int i = 1; i <= n; i ++ )
    {
        if(ok[i])
            s[++ len] = t[i];
        else s[++ len] = idx --;
        s[++ len] = M1;
    }
}

inline int manacher(int len)
{
    for(int i=0;i<=len;i++) f[i]=0;
    int mid = 0, r = 0;
    for(register int i = 1; i <= len; i ++ )
    {
        if(s[i] < 0) continue;
        if(i <= r) f[i] = min(f[2 * mid - i], r - i + 1);
        while(s[i + f[i]] == s[i - f[i]] && i - f[i] >= 1 && i + f[i] <= len) 
            f[i] ++;
        if(i + f[i] > r) r = i + f[i] - 1, mid = i;
    }
    int ans = 0;
    for(int i = 1; i <= len; i ++ ) ans += f[i] / 2;
    return ans;
}

int main()
{
    #ifdef LOCAL
        freopen("D:\\workspace\\in_and_out\\in.in", "r", stdin);
        freopen("D:\\workspace\\in_and_out\\out.out", "w", stdout);
    #endif

    double st = clock();

    n = read(), m = read();
    for(register int i = 1; i <= n; i ++ ) scanf("%s", a[i] + 1);
    p[0] = 1;
    for(register int i = 1; i < N - 5; i ++ ) p[i] = p[i - 1] * P % mod;

    for(register int i = 1; i <= n; i ++ )
        for(register int j = 1; j <= m; j ++ )
        {
            for(register int k = 0; k < 26; k ++ )
                cnt[i][j][k] = cnt[i][j - 1][k];
            cnt[i][j][a[i][j] - 'a'] ++;
        }
    
    for(register int L = 1; L <= m; L ++ )
    {
        for(register int R = L; R <= m; R ++ )
        {
            idx = -5;
            for(int k=1;k<=n;k++) ok[k]=false;
            for(register int k = 1; k <= n; k ++ )
                t[k] = gethash(k, L, R);
            init();
            ans += manacher(len);
        }
    }

    cout << ans << endl;
    // cout << (clock() - st) / CLOCKS_PER_SEC << endl;

    return 0;
}
2023/5/19 18:08
加载中...