a題:
題意:求所有全為1的矩陣且每個子矩陣都不會被其他矩陣完全包含的子矩陣的個數。
分析:最近遇到的全1子矩陣的題有點多額....,可是還是不怎麼會做。但基本都用了單調棧....
設h[i][j]表示第i行以j點為底點的最高連續的1的個數,可以用單調棧求使j點以h[i][j]為高度的矩形的左右邊界(懸線法也可以)
然後,統計個數,此時就要去重了,相同的行去重可以通過單調棧來判斷,每一行構造單調遞增的棧,是否棧頂和h[i][j]相等,如果相等即為重複,不同的行去重是通過字首和,判斷第i行第j個點是否可以通過sum[i+1][r[j]]-sum[i+1][l[j]-1]!=r[j]-l[j]+1來判斷,如果不等表示下一行從l[j]到r[j]不全是1,即第i行的那個矩陣不會被包含。
ac code:
#include using namespace std;
const int maxn=3005;
typedef long long ll;
int a[maxn][maxn],l[maxn],r[maxn];
int sum[maxn][maxn],h[maxn][maxn];
stackst;
int main()
int ans=0;
for(int i=1; i<=n; i++)
while(!st.empty()) st.pop();
st.push(m+1);
for(int j=m;j>=1;--j)
while(!st.empty()) st.pop();
for(int j=1; j<=m; j++)
while(!st.empty()&&h[i][j]類似的還有第四場的牛客c題:
也是用單調棧求出使a[i]最小的左右邊界,然後維護字首和的線段樹而已。
ac code:
#includeusing namespace std;
typedef long long ll;
const int maxn=3e6+2;
const ll inf=1e18;
struct treetree[maxn<<2];
ll pre[maxn];
int l[maxn],r[maxn],n,a[maxn],b[maxn];
stacks;
void init()
s.push(i);}}
while(!s.empty()) r[s.top()]=n+1,s.pop();
for(int i=n;i>=1;i--)
s.push(i);}}
while(!s.empty()) l[s.top()]=0,s.pop();
}void pushup(int rt)
void buildtree(int rt,int l,int r)
int mid=(l+r)>>1;
buildtree(rt<<1,l,mid);
buildtree(rt<<1|1,mid+1,r);
pushup(rt);
}ll query(int rt,int l,int r,int l,int r,bool flag)///flag=1查最大
int mid=(l+r)>>1;
if(flag)
printf("%lld\n",ans);
return 0;
}
最後貼乙個大佬的全01子矩陣計數的部落格: 2019牛客暑期多校訓練營(第八場
現場ac a,b,c,g rank 185題號a bcde fghi jkl狀態 a 2維單調棧 從上到下 每行建乙個單調棧,維護的是1向上擴充套件最遠的高度。得到每個高度所向左向右擴充套件的最遠距離,即每個點拓展 先向上到頂 的最大全1子矩陣,求出這個個數ans,再減去同樣高度的,和可向下拓展的 ...
2019牛客暑期多校訓練營(第八場)
practice link solvedab cdef ghij k4 11 o ooa.all one matrices 點這裡 b.beauty values 點這裡 c.cdma 構造 題意 構造由 1,1組成的m m矩陣,使得任意兩個不同 這裡指的是數字有不同的地方 的行對應位置乘積和為0 ...
2019牛客暑期多校訓練營(第八場
solved by rdc 84min 2 做法 題意構造矩陣,使得任意兩行點積為 0 做法樣例具有很強的暗示性,我們可以用 k 階矩陣,構造 k 1 階矩陣。題意三維空間,插入點,查詢與某個點曼哈頓距離最小點。比賽中做法 做法2.0 做法 upsolved 問題的轉化 注意到標號為 x 的點,在每...