• 笛卡尔树-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

    笛卡尔树它多可爱呀~

  • 相关阅读:
    【hive】时间段为五分钟的统计
    【git】提交到github不显示贡献小绿点问题的解决
    【hive】关于用户留存率的计算
    【hive】求日期是星期几
    【hive】数据仓库层次设计
    【hive】count() count(if) count(distinct if) sum(if)的区别
    转载:几种 hive join 类型简介
    丑小鸭和白天鹅没有区别
    好好照顾自己,就像照顾你爱的人那样;
    灵光一闪(最近更新于2020/8/23)
  • 原文地址:https://www.cnblogs.com/BrotherHood/p/13994790.html
Copyright © 2020-2023  润新知