zoukankan      html  css  js  c++  java
  • 笛卡尔树-P2659 美丽的序列

    P2659 美丽的序列

    tag 笛卡尔树

    题意

    找出一个序列的所有子段中子段长度乘段内元素最小值的最大值。

    思路

    我们需要找出所有子段中贡献最大的,并且一个子段的贡献为其长度乘区间最小值

    这……不就是裸的笛卡尔树吗?

    建出符合小根堆性质的笛卡尔树,递归所有点,更新答案即可。

    因为这是一道裸题,所以我记录一下建笛卡尔树的模板。(从OI wiki上扣的)

    思路是用一个单调栈维护一下右链。

    伪代码:

    新建一个大小为 n 的空栈。用 top 来标操作前的栈顶,k 来标记当前栈顶。
    For i := 1 to n
        k := top
        While 栈非空 且 栈顶元素 > 当前元素 
            k--
        if 栈非空
            栈顶元素.右儿子 := 当前元素
        if k < top
            当前元素.左儿子 := 之前栈顶元素
        当前元素入栈
        top := k
    

    C++:

    for(int k,i=1;i<=n;i++){
        k=top;
        while(k and a[st[k]]>a[i])k--;
        if(k) rs[st[k]]=i,isrt[i]=1;
        if(k<top) ls[i]=st[k+1],isrt[st[k+1]]=1;
        st[++k]=i;
        top=k;
    }
    

    本题实现

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cctype>
    #include<cstring>
    #include<cmath>
    using namespace std;
    inline int read(){
    	int w=0,x=0;char c=getchar();
    	while(!isdigit(c))w|=c=='-',c=getchar();
    	while(isdigit(c))x=x*10+(c^48),c=getchar();
    	return w?-x:x;
    }
    namespace star
    {
    	const int maxn=2e6+10;
    	int n,a[maxn],ls[maxn],rs[maxn],st[maxn],top;
    	long long ans;
    	bool isrt[maxn];
    	void dfs(int x,int l,int r){
    		ans=max(ans,1ll*a[x]*(r-l+1));
    		if(ls[x])dfs(ls[x],l,x-1);
    		if(rs[x])dfs(rs[x],x+1,r);
    	}
    	inline void work(){
    		n=read();
    		for(int i=1;i<=n;i++) a[i]=read();
    		for(int k,i=1;i<=n;i++){
    			k=top;
    			while(k and a[st[k]]>a[i])k--;
    			if(k) rs[st[k]]=i,isrt[i]=1;
    			if(k<top) ls[i]=st[k+1],isrt[st[k+1]]=1;
    			st[++k]=i;
    			top=k;
    		}
    		int root=0;
    		for(int i=1;i<=n;i++) if(!isrt[i]) root=i;
    		dfs(root,1,n);
    		printf("%lld
    ",ans);
    	}
    }
    signed main(){
    	star::work();
    	return 0;
    }
    

    其他

    为什么你谷连带log的做法都有就是没人写笛卡尔树呀QAQ

    笛卡尔树它多可爱呀~

  • 相关阅读:
    32-Ubuntu-用户权限-03-修改文件权限
    31-Ubuntu-用户权限-02-ls输出信息介绍
    hdu2084 数塔
    hdu 1058 humble number
    HDU_2050 折线分割平面
    HDU_1030 Delta-wave 常数时间
    HDU_1021 Fibonacci Again 一些推论
    Gated Recurrent Unit(GRU)
    循环神经网络模型
    Bellman-Ford algorithm
  • 原文地址:https://www.cnblogs.com/BrotherHood/p/13994790.html
Copyright © 2011-2022 走看看