題意
給你一個的只包含四種顏色的網格。
此詢問,每次問一個矩陣中所包含的形如以下格式的的最大面積
題解
如何確定包含某個點的最大純色正方形?
只考慮以點爲右下角的顏色爲的最大正方形的邊長,設其爲.
則有:
如何確定包含某個點的最大的?
考慮紅色方塊的右下角,則邊長爲的合法的充要條件爲:
當存在這樣的滿足上述條件時,記.
如何確定某個矩陣內的最大?
先考慮如何判定邊長爲的是否存在.
因爲所記錄的爲紅色方塊的右下角,故可以確定的選點範圍爲子矩陣
如果存在這樣的,也就是子矩陣中存在,也就是子矩陣內.
可以發現的有單調性的,故可以通過二分找到最大的.
考慮另外一種思路
在第二步時記滿足條件式的最大的爲.
那麼在第三步時的判定條件將變爲子矩陣中.
總結下來題目體質就是求矩陣和或矩陣最大值.
具體方法爲:
預處理前綴和,差分,時間複雜度,空間複雜度.
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];
}
二維表,時間複雜度,空間複雜度.
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]));
}
注意:參照點不止右下角一種選法,參照點選取的不同方案隻影響子矩陣的範圍和判定合法所選取的.