[Codeforces1301E]Nanosoft

题意

给你一个 n × m n\times m n×m的只包含四种颜色的网格。

q q q此询问,每次问一个矩阵中所包含的形如以下格式的 L o g o Logo Logo的最大面积

[Codeforces1301E]Nanosoft_第1张图片
1 ≤ n , m ≤ 500 , 1 ≤ q ≤ 3 ⋅ 1 0 5 1\le n,m\le500,1\le q\le3\cdot10^5 1n,m500,1q3105

题解

1. 1. 1.如何确定包含某个点的最大纯色正方形?

只考虑以点 ( i , j ) (i,j) (i,j)为右下角的颜色为 p p p的最大正方形的边长,设其为 L p , i , j L_{p,i,j} Lp,i,j.

则有:
L p , i , j = { 0 , c o l o r i , j ≠ p min ⁡ { L p , i − 1 , j , L p , i , j − 1 , L p , i − 1 , j − 1 } + 1 , c o l o r i , j = p L_{p,i,j}=\left\{ \begin{aligned} & 0 & , color_{i,j}\neq p\\ & \min\{L_{p,i-1,j},L_{p,i,j-1},L_{p,i-1,j-1}\}+1 & , color_{i,j}=p \end{aligned}\right. Lp,i,j={0min{Lp,i1,j,Lp,i,j1,Lp,i1,j1}+1,colori,j=p,colori,j=p

2. 2. 2.如何确定包含某个点的最大的 L o g o Logo Logo?

考虑红色方块的右下角 ( i , j ) (i,j) (i,j),则边长为 2 k 2k 2k L o g o Logo Logo合法的充要条件为:

L R , i , j ≥ k   a n d   L G , i , j + k ≥ k   a n d   L B , i + k , j + k ≥ k   a n d   L Y , i + k , j ≥ k L_{R,i,j}\ge k{\rm\ and\ }L_{G,i,j+k}\ge k{\rm\ and\ }L_{B,i+k,j+k}\ge k{\rm\ and\ }L_{Y,i+k,j}\ge k LR,i,jk and LG,i,j+kk and LB,i+k,j+kk and LY,i+k,jk

当存在这样的 i , j , k i,j,k i,j,k满足上述条件时,记 S k , i , j = 1 S_{k,i,j}=1 Sk,i,j=1.

3. 3. 3.如何确定某个矩阵内的最大 L o g o Logo Logo?

先考虑如何判定边长为 2 k 2k 2k L o g o Logo Logo是否存在.

因为所记录的 ( i , j ) (i,j) (i,j)为红色方块的右下角,故可以确定 ( i , j ) (i,j) (i,j)的选点范围为子矩阵 : : :

r 1 − k + 1 ≤ i ≤ r 2 − k , c 1 − k + 1 ≤ j ≤ c 2 − k r_1-k+1\le i\le r_2-k,c_1-k+1\le j\le c_2-k r1k+1ir2k,c1k+1jc2k

如果存在这样的 L o g o Logo Logo,也就是子矩阵中存在 S k , i , j = 1 S_{k,i,j}=1 Sk,i,j=1,也就是子矩阵内 ∑ S k , i , j > 0 \sum S_{k,i,j}>0 Sk,i,j>0.

可以发现 k k k的有单调性的,故可以通过二分找到最大的 k k k.

4. 4. 4.考虑另外一种思路

在第二步时记满足条件式的最大的 k k k f i , j f_{i,j} fi,j.

那么在第三步时的判定条件将变为 : : :子矩阵中 max ⁡ f i , j ≥ k \max f_{i,j}\ge k maxfi,jk.


总结下来题目体质就是求矩阵和或矩阵最大值.

具体方法为:

a ) a) a)预处理前缀和,差分,时间复杂度 O ( n 3 + q log ⁡ n ) O(n^3+q\log n) O(n3+qlogn),空间复杂度 O ( n 3 ) O(n^3) O(n3).

inline void Prepare(){
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
            for(k=min(min(i,n-i),min(j,m-j));k>=1;--k){
                S[k][i][j]=S[k][i-1][j]+S[k][i][j-1]-S[k][i-1][j-1];
                if(L[0][i][j]>=k&&L[1][i][j+k]>=k&&L[2][i+k][j+k]>=k&&L[3][i+k][j]>=k){
                    for(int l=k;l>=1;--l)
                        S[l][i][j]=S[l][i-1][j]+S[l][i][j-1]-S[l][i-1][j-1]+1;
                    break;
                }
            }
}
inline bool Qry(int x1,int y1,int x2,int y2,int k){
    return S[k][x2][y2]-S[k][x1-1][y2]-S[k][x2][y1-1]+S[k][x1-1][y1-1];
}

b ) b) b)二维 S T ST ST表,时间复杂度 O ( n 3 + q log ⁡ n ) O(n^3+q\log n) O(n3+qlogn),空间复杂度 O ( n 2 log ⁡ 2 n ) O(n^2\log^2n) O(n2log2n).

inline void Prepare(){
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
            for(k=min(min(i,n-i),min(j,m-j));k>=1;--k)
                if(L[0][i][j]>=k&&L[1][i][j+k]>=k&&L[2][i+k][j+k]>=k&&L[3][i+k][j]>=k){
                    f[0][0][i][j]=k;break;
                }
    for(int k=0;k<=Log[n];++k)
        fp(int l=0;l<=Log[m];++l)
            if(k||l)
                for(int i=1;i+(1<<k)-1<=n;++i)
                    for(int j=1;j+(1<<l)-1<=n;++j)
                        f[k][l][i][j]=l?max(f[k][l-1][i][j],f[k][l-1][i][j+(1<<(l-1))]):
                            max(f[k-1][l][i][j],f[k-1][l][i+(1<<(k-1))][j]);
}
inline bool Qry(int x1,int y1,int x2,int y2,int k){
    int Lx=Log[x2-x1+1],Ly=Log[y2-y1+1];
    return k<=max(max(f[Lx][Ly][x1][y1],f[Lx][Ly][x2-(1<<Lx)+1][y2-(1<<Ly)+1]),
            max(f[Lx][Ly][x2-(1<<Lx)+1][y1],f[Lx][Ly][x1][y2-(1<<Ly)+1]));
}

注意:参照点不止右下角一种选法,参照点选取的不同方案只影响子矩阵的范围和判定合法所选取的 L p , x , y L_{p,x,y} Lp,x,y.

你可能感兴趣的:(#,二分答案,#,前缀和,ST表)