B4273 [蓝桥杯青少年组省赛 2023] 最大的矩形纸片
B4273 [蓝桥杯青少年组省赛 2023] 最大的矩形纸片
大意
直方图中的最大矩形
思路
首先这个题目要求的是长直图中最大的矩形,我们考虑用笛卡尔树去完成这个题目。
首先我们以高度为点权建立笛卡尔树,然后我们如果知道一个点有多少个子节点,那么这个点的矩形并的答案为 \(h[i] * sz[i]\),最后全部跑一次即可。
当然,朴素的单调栈也未尝不可,但是笛卡尔树更加形象。
代码
#include<iostream>
#include<stack>
using namespace std;
#define int long long
const int MAXN = 1e6 + 10;
int n, a[MAXN];
int l[MAXN], r[MAXN];
int sz[MAXN], in[MAXN], ans;
stack<int> st;
int dfs(int x){
sz[x] = 1;
if(l[x]) sz[x] += dfs(l[x]);
if(r[x]) sz[x] += dfs(r[x]);
return sz[x];
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
for(int i = 1;i <= n;i ++){
cin >> a[i];
}
st.push(1);
for(int i = 2;i <= n;i ++){
int lst = st.top();
while(!st.empty() && a[i] < a[st.top()]){
lst = st.top();
st.pop();
}
if(st.empty()){
l[i] = lst;
}
else{
l[i] = r[st.top()];
r[st.top()] = i;
}
st.push(i);
in[l[i]] ++;
in[r[i]] ++;
}
for(int i = 1;i <= n;i ++){
if(!in[i]){
int c = dfs(i);
}
}
int ans = 0;
for(int i = 1;i <= n;i ++){
ans = max(ans, a[i] * sz[i]);
}
cout << ans << '\n';
return 0;
}
本文来自一名高中生,作者:To_Carpe_Diem

浙公网安备 33010602011771号