[Codeforces1301E]Nanosoft

題意

給你一個n×mn\times m的只包含四種顏色的網格。

qq此詢問,每次問一個矩陣中所包含的形如以下格式的LogoLogo的最大面積


1n,m500,1q31051\le n,m\le500,1\le q\le3\cdot10^5

題解

1.1.如何確定包含某個點的最大純色正方形?

只考慮以點(i,j)(i,j)爲右下角的顏色爲pp的最大正方形的邊長,設其爲Lp,i,jL_{p,i,j}.

則有:
Lp,i,j={0,colori,jpmin{Lp,i1,j,Lp,i,j1,Lp,i1,j1}+1,colori,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.

2.2.如何確定包含某個點的最大的LogoLogo?

考慮紅色方塊的右下角(i,j)(i,j),則邊長爲2k2kLogoLogo合法的充要條件爲:

LR,i,jk and LG,i,j+kk and LB,i+k,j+kk and LY,i+k,jkL_{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

當存在這樣的i,j,ki,j,k滿足上述條件時,記Sk,i,j=1S_{k,i,j}=1.

3.3.如何確定某個矩陣內的最大LogoLogo?

先考慮如何判定邊長爲2k2kLogoLogo是否存在.

因爲所記錄的(i,j)(i,j)爲紅色方塊的右下角,故可以確定(i,j)(i,j)的選點範圍爲子矩陣::

r1k+1ir2k,c1k+1jc2kr_1-k+1\le i\le r_2-k,c_1-k+1\le j\le c_2-k

如果存在這樣的LogoLogo,也就是子矩陣中存在Sk,i,j=1S_{k,i,j}=1,也就是子矩陣內Sk,i,j>0\sum S_{k,i,j}>0.

可以發現kk的有單調性的,故可以通過二分找到最大的kk.

4.4.考慮另外一種思路

在第二步時記滿足條件式的最大的kkfi,jf_{i,j}.

那麼在第三步時的判定條件將變爲::子矩陣中maxfi,jk\max f_{i,j}\ge k.


總結下來題目體質就是求矩陣和或矩陣最大值.

具體方法爲:

a)a)預處理前綴和,差分,時間複雜度O(n3+qlogn)O(n^3+q\log n),空間複雜度O(n3)O(n^3).

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)二維STST表,時間複雜度O(n3+qlogn)O(n^3+q\log n),空間複雜度O(n2log2n)O(n^2\log^2n).

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]));
}

注意:參照點不止右下角一種選法,參照點選取的不同方案隻影響子矩陣的範圍和判定合法所選取的Lp,x,yL_{p,x,y}.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章