zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Nginx 静态资源缓存设置
    Ubuntu Linux 与 Windows 7双系统安装教程(图文)
    配置可以通过http协议访问的svn服务器
    CentOS下搭建SVN服务器
    LINUX服务器下用root登录ftp
    CentOS 6下编译安装MySQL 5.6
    Jenkins代码管理
    python学习:备份文档并压缩为zip格式
    centos 7 双网卡建网桥脚本实现
    python学习:使用正则收集ip信息
  • 原文地址:https://www.cnblogs.com/CJLHY/p/11804782.html
Copyright © 2011-2022 走看看