給出乙個n*m 的01 矩陣,求其中有多少個連續子矩陣,使得其面積大於等於k,且其中不包含1。
非常經典的一道題目。
首先我們很容易知道n^3的方法。
那麼我們來優化一下。
我們先求出f[i][j]表示從(i,j)向右連續1的數量。
然後把這些從大到小的插入(桶排一下)
然後如果上面或下面已經有了就合併,然後算出貼底的(就是有一邊在第j列)的新增矩形方案數,第j+1列插入f[1~n][j+1]的時候會考慮。
然後合併的時候就要考慮跨越中間的分界線且高度不超過h的新增矩形,那麼新增矩形就是f[h][size[u]+size[v]]-f[h][size[u]]-f[h][size[v]]
設f[i][j]為在長為i,寬為j的矩形類,貼著j那條邊的面積》k的矩形數量。 那麼f
[i][
j]=f
[i][
j−1]
+∑ik
=1g[
k][i
] g[i][j]表示底為i,高不大於j,面積》k的矩形數量,可以直接求出來g[
i][j
]=j−
⌈ki⌉
+1然後g字首和一下就好了,改一下列舉i,j的順序,g陣列可以只用乙個變數。
合併用並查集維護
複雜度o(n^2logn)
也可以維護每塊的最左最右端點,可以省掉log
#include
#include
#include
#include
#include
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fod(i,a,b) for(i=a;i>=b;i--)
using namespace std;
typedef long long ll;
const int maxn=4007;
int i,j,k,l,t,n,m,x,y,o;
int a[maxn][maxn],f[maxn][maxn],c[maxn];
int b[maxn*maxn][2],fa[maxn*maxn],size[maxn*maxn],p;
bool bz[maxn][maxn];
ll ans,g[maxn][maxn];
int gf(int x)
int get()
void merge(int x,int y,int h)
int de(int x,int y)
int main()
}fo(i,1,n)fo(j,1,m)
fo(i,1,m)c[i]+=c[i-1];
fo(i,1,n)fo(j,1,m)
b[c[f[i][j]]][0]=i,b[c[f[i][j]]--][1]=j;
fod(i,n*m,1)
printf("%lld\n",ans);
}
JZOJ5242 GDOI2018模擬8 8 矩陣
description 給出乙個n m 的01 矩陣,求其中有多少個連續子矩陣,使得其面積大於等於k,且其中不包含1。input 第一行為用空格隔開的三個整數n,m,k。分別表示矩陣的行數,列數和子矩陣的最小面積。接下來的n 行每行為用空格隔開的m 個整數,為題目中給出的矩陣。output 輸出一行...
JZOJ5233 GDOI模擬 概率博弈
小a和小b在玩遊戲。這個遊戲是這樣的 有一棵n個點的以1為根的有根樹,葉子有權值。假設有m個葉子,那麼樹上每個葉子的權值序列就是乙個1 m 的排列。一開始在1號點有一顆棋子。兩人輪流將這顆棋子移向其當前位置的乙個兒子。假如棋子到達葉子,遊戲結束,最終獲得的權值為所在葉子對應權值。小a希望最後的權值盡...
JZOJ3400 GDOI2014模擬 旅行
給你乙個圖,讓你選擇權值和最小的邊,使得 1 和 n 2 和 n 1 k 和 n k 1 聯通。k leq 4 一看到這題就覺得特別神仙 然後去思考網路流 搞出了乙個最小割,後來發現這是錯的 匆匆打了個表,獲得了這題的十分之一的分數。其實這題有水法,許多人是全排列 spfa 跑了一遍之後將路過的邊清...