51nod 1102 面积最大的矩形 (笛卡尔树)

之前用的单调栈解决的,这次发现了一个新方法 笛卡尔树,记录一下

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=100005;
int n,a[maxn],ls[maxn],rs[maxn],fa[maxn],stk[maxn],top=0,sum[maxn];
long long ans;
inline int read(){
    int ret=0,f=1;char ch=getchar();
    while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
    return ret*f;
}
inline void DFS(int x){
    if (x<1||x>n) return;
    if ((long long)(sum[ls[x]]+sum[rs[x]]+1)*(long long)a[x]>ans) ans=(long long)(sum[ls[x]]+sum[rs[x]]+1)*(long long)a[x];
    sum[x]=sum[ls[x]]+sum[rs[x]]+1;
    DFS(fa[x]);
}
int main(){
    n=read();
    for (int i=1;i<=n;i++) a[i]=read();
    for (int i=1;i<=n;i++){
        if (a[i]>=a[stk[top]]||top==0){
            rs[stk[top]]=i;
            fa[i]=stk[top];
            stk[++top]=i;
        } else {
            while (a[stk[top]]>a[i]&&top>=1) top--;
            rs[stk[top]]=i;fa[i]=stk[top];
            ls[i]=stk[top+1];fa[stk[top+1]]=i;rs[i]=0;
            stk[++top]=i;
        }
    }
    for (int i=1;i<=n;i++) if (ls[i]==0&&rs[i]==0) DFS(i);
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/wzazzy/article/details/83549675
今日推荐