• [luoguP2601] [ZJOI2009]对称的正方形(二维Hash + 二分 || Manacher)


    传送门

    很蒙蔽,不知道怎么搞。

    网上看题解有说可以哈希+二分搞,也有的人说用Manacher搞,Manacher是什么鬼?以后再学。

    对于这个题,可以从矩阵4个角hash一遍,然后枚举矩阵中的点,再二分半径。

    但是得考虑边的长度为奇偶所带来的影响。

    比如

    1 1

    1 1

    这个边数为偶数的矩阵显然没法搞。

    所以得在矩阵中插入0,

    变成

    0 0 0 0 0

    0 1 0 1 0

    0 0 0 0 0

    0 1 0 1 0

    0 0 0 0 0

    具体操作就看代码好了。

    然后只枚举 行 + 列 为偶数的点就行。

    注意 用 unsigned long long 会超时和超空间,数据允许用 unsigned int

    ——代码

      1 #include <cstdio>
      2 #include <iostream>
      3 #define UI unsigned int
      4 
      5 const int MAXN = 2010, bs1 = 19260817, bs2 = 20011001;
      6 int n, m, ans;
      7 UI sum[4][MAXN][MAXN], base1[MAXN], base2[MAXN];
      8 
      9 inline int read()
     10 {
     11     int x = 0, f = 1;
     12     char ch = getchar();
     13     for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
     14     for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
     15     return x * f;
     16 }
     17 
     18 inline int min(int x, int y)
     19 {
     20     return x < y ? x : y;
     21 }
     22 
     23 inline bool pd(int x, int y, int l)
     24 {
     25     UI t, h;
     26     h = sum[0][x + l - 1][y + l - 1]
     27       -    sum[0][x - l][y + l - 1] * base1[l + l - 1]
     28       - sum[0][x + l - 1][y - l] * base2[l + l - 1]
     29       + sum[0][x - l][y - l] * base1[l + l - 1] * base2[l + l - 1];
     30     t = sum[1][x + l - 1][y - l + 1]
     31       - sum[1][x - l][y - l + 1] * base1[l + l - 1]
     32       - sum[1][x + l - 1][y + l] * base2[l + l - 1]
     33       + sum[1][x - l][y + l] * base1[l + l - 1] * base2[l + l - 1];
     34     if(h ^ t) return 0;
     35     t = sum[2][x - l + 1][y + l - 1]
     36       - sum[2][x + l][y + l - 1] * base1[l + l - 1]
     37       - sum[2][x - l + 1][y - l] * base2[l + l - 1]
     38       + sum[2][x + l][y - l] * base1[l + l - 1] * base2[l + l - 1];
     39     if(h ^ t) return 0;
     40     t = sum[3][x - l + 1][y - l + 1]
     41       - sum[3][x + l][y - l + 1] * base1[l + l - 1]
     42       - sum[3][x - l + 1][y + l] * base2[l + l - 1]
     43       + sum[3][x + l][y + l] * base1[l + l - 1] * base2[l + l - 1];
     44     if(h ^ t) return 0;
     45     return 1;
     46 }
     47 
     48 inline int work(int i, int j)
     49 {
     50     int mid, s = 0, x = 1, y = min(min(i, n - i + 1), min(j, m - j + 1));//二分半径 
     51     while(x <= y)
     52     {
     53         mid = (x + y) >> 1;
     54         if(pd(i, j, mid)) s = mid, x = mid + 1;
     55         else y = mid - 1;
     56     }
     57     return s;
     58 }
     59 
     60 int main()
     61 {
     62     int i, j, k, x;
     63     n = read();
     64     m = read();
     65     n = n << 1 | 1;
     66     m = m << 1 | 1;
     67     for(i = 2; i <= n; i += 2)
     68         for(j = 2; j <= m; j += 2)
     69         {
     70             x = read();
     71             for(k = 0; k < 4; k++) sum[k][i][j] = x;
     72         }
     73     base1[0] = base2[0] = 1;
     74     for(i = 1; i <= n; i++) base1[i] = base1[i - 1] * bs1;
     75     for(i = 1; i <= m; i++) base2[i] = base2[i - 1] * bs2;
     76     for(i = 1; i <= n; i++)
     77         for(j = 1; j <= m; j++)
     78             sum[0][i][j] += sum[0][i - 1][j] * bs1;
     79     for(i = 1; i <= n; i++)
     80         for(j = 1; j <= m; j++)
     81             sum[0][i][j] += sum[0][i][j - 1] * bs2;
     82     for(i = 1; i <= n; i++)
     83         for(j = m; j; j--)
     84             sum[1][i][j] += sum[1][i - 1][j] * bs1;
     85     for(i = 1; i <= n; i++)
     86         for(j = m; j; j--)
     87             sum[1][i][j] += sum[1][i][j + 1] * bs2;
     88     for(i = n; i; i--)
     89         for(j = 1; j <= m; j++)
     90             sum[2][i][j] += sum[2][i + 1][j] * bs1;
     91     for(i = n; i; i--)
     92         for(j = 1; j <= m; j++)
     93             sum[2][i][j] += sum[2][i][j - 1] * bs2;
     94     for(i = n; i; i--)
     95         for(j = m; j; j--)
     96             sum[3][i][j] += sum[3][i + 1][j] * bs1;
     97     for(i = n; i; i--)
     98         for(j = m; j; j--)
     99             sum[3][i][j] += sum[3][i][j + 1] * bs2;
    100     for(i = 1; i <= n; i++)
    101         for(j = 1; j <= m; j++)
    102             if((i ^ j ^ 1) & 1)
    103                 ans += work(i, j) >> 1;
    104     printf("%d
    ", ans);
    105     return 0;
    106 }
    View Code

    Manacher的话,学完再搞吧。

  • 相关阅读:
    Linux命令应用大词典-第11章 Shell编程
    Kubernetes 学习12 kubernetes 存储卷
    linux dd命令
    Kubernetes 学习11 kubernetes ingress及ingress controller
    Kubernetes 学习10 Service资源
    Kubernetes 学习9 Pod控制器
    Kubernetes 学习8 Pod控制器
    Kubernetes 学习7 Pod控制器应用进阶2
    Kubernetes 学习6 Pod控制器应用进阶
    Kubernetes 学习5 kubernetes资源清单定义入门
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6863532.html
Copyright © 2020-2023  润新知