51nod 1102 面積最大的矩形 (笛卡爾樹)
阿新 • • 發佈:2018-11-02
之前用的單調棧解決的,這次發現了一個新方法 笛卡爾樹,記錄一下
#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; }