• Codeforces 1080E Sonya and Matrix Beauty hash + manacher


    Sonya and Matrix Beauty

    处理子矩阵的一般方法, 把多行压缩成一行,然后跑manacher, 压缩的话用hash就好了。

    #include<bits/stdc++.h>
    using namespace std;
    
    using LL = long long;
    using ull = unsigned long long ;
    
    mt19937_64 rng(58);
    
    const int N = 250 + 7;
    const ull B = (int)1e6 + 3;
    
    int n, m;
    int c[N][N][26];
    char s[N][N];
    ull Pow[26];
    ull V[N];
    int p[N];
    int odd;
    
    inline ull get(int row, int l, int r, int ch) {
        int cnt = c[row][r][ch] - c[row][l - 1][ch];
        odd += cnt & 1;
        return cnt * Pow[ch];
    }
    
    int manacher(ull *s, int n) {
        int ans = 0;
        s[0] = rng(); s[n + 1] = rng();
        int mx = 0, id = 0;
        for(int i = 1; i <= n; i++) {
            if(mx > i) p[i] = min(mx - i, p[2 * id - i]);
            else p[i] = 1;
            while(s[i + p[i]] == s[i - p[i]]) p[i]++;
            if(i + p[i] > mx) mx = i + p[i], id = i;
            ans += p[i];
        }
        mx = 0, id = 0;
        for(int i = 1; i <= n; i++) {
            if(mx > i) p[i] = min(mx - i, p[2 * id - i]);
            else p[i] = 0;
            while(s[i + p[i] + 1] == s[i - p[i]]) p[i]++;
            if(i + p[i] > mx) mx = i + p[i], id = i;
            ans += p[i];
        }
        return ans;
    }
    
    int main() {
        for(int i = Pow[0] = 1; i < N; i++) Pow[i] = Pow[i - 1] * B;
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++) scanf("%s", s[i] + 1);
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                for(int k = 0; k < 26; k++) c[i][j][k] = c[i][j - 1][k];
                c[i][j][s[i][j] - 'a']++;
            }
        }
        LL ans = 0;
        for(int cl = 1; cl <= m; cl++) {
            for(int cr = cl; cr <= m; cr++) {
                int tot = 0;
                for(int r = 1; r <= n; r++) {
                    ull hs = 0; odd = 0;
                    for(int ch = 0; ch < 26; ch++) {
                        hs += get(r, cl, cr, ch);
                    }
                    V[r] = hs;
                    if((cr - cl & 1) && odd || !(cr - cl & 1) && odd > 1) {
                        ans += manacher(V, tot);
                        tot = 0;
                    }
                    else {
                        V[++tot] = hs;
                    }
                }
                ans += manacher(V, tot);
            }
        }
        printf("%lld
    ", ans);
        return 0;
    }
  • 相关阅读:
    Firefox for macOS 标签关闭按钮设置在左侧
    Nginx 非编译安装 stream 模块实现四层负载均衡
    苹果手机卡死,强制关机方法
    Git安装完成,文件夹下右键菜单不出现出现Git Bash Here 和Git UI Here问题
    AESUtil
    若依框架清空select2选择
    RSAUtils
    springboot 延时任务
    Mqtt的坑,真的坑
    springboot 支付宝支付业务网页端扫码
  • 原文地址:https://www.cnblogs.com/CJLHY/p/11804782.html
Copyright © 2020-2023  润新知