2019牛客暑期多校訓練營(第八場)補題

2021-09-26 02:46:45 字數 1725 閱讀 8919

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 的點,在每...