• 2023牛客OI赛前集训营-提高组(第一场) 情景剧


    题目大意

    有一个长度为 n n n的序列 h i h_i hi,一段区间 [ l , r ] [l,r] [l,r]的有趣程度为这段区间上 h i h_i hi的最大值 × \times ×最小值 × \times ×区间长度。求所有区间中有趣程度的最大值,输出这个最大值。

    保证答案在 unsigned long long \text{unsigned long long} unsigned long long的范围内。

    1 ≤ n ≤ 2 × 1 0 6 , 1 ≤ h i ≤ 1 0 9 1\leq n\leq 2\times 10^6,1\leq h_i\leq 10^9 1n2×106,1hi109


    题解

    假设我们已经确定了区间的最小值 h i h_i hi,那么对于包含 h i h_i hi的区间 [ l , r ] [l,r] [l,r],在保证区间中 h i h_i hi为最小值的情况下,则区间长度肯定是越大越好(因为取的数越多,最大值只会增大或不变,而区间长度只会增大,有趣程度也就不断增大了)。

    也就是说,对于每个 h i h_i hi,求出以 h i h_i hi最小值的最大区间,并用这个区间来更新答案即可。

    那怎么求以 h i h_i hi最小值的最大区间呢?用并查集可以解决。

    我们可以按 h i h_i hi的值从大到小枚举 h i h_i hi,对于一个 h i h_i hi,如果 h i − 1 h_{i-1} hi1在之前就被枚举过了,那么显然其值是比 h i h_i hi大的,其所在联通块的最小值也一定比 h i h_i hi大(在连通块中的都是在之前被枚举过的 h h h值),那么就将 h i h_i hi加入 h i − 1 h_{i-1} hi1所在的连通块。对 h i + 1 h_{i+1} hi+1也是如此。然后, h i h_i hi所在的连通块即为以 h i h_i hi最小值的最大区间,用这个区间更新答案即可。

    时间复杂度为 O ( n ⋅ α ( n ) ) O(n\cdot \alpha(n)) O(nα(n))

    code

    #include
    using namespace std;
    int n,v[2000005],id[2000005],fa[2000005],siz[2000005],z[2000005];
    unsigned long long mn[2000005],mx[2000005];
    unsigned long long ans=0;
    bool cmp(int ax,int bx){
    	return v[ax]>v[bx];
    }
    int find(int ff){
    	if(fa[ff]!=ff) fa[ff]=find(fa[ff]);
    	return fa[ff];
    }
    void pt(int x,int y){
    	x=find(x);y=find(y);
    	if(x==y) return;
    	fa[y]=x;
    	siz[x]+=siz[y];
    	mn[x]=min(mn[x],mn[y]);
    	mx[x]=max(mx[x],mx[y]);
    	ans=max(ans,mx[x]*mn[x]*siz[x]);
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++){
    		scanf("%d",&v[i]);
    		ans=max(ans,1ull*v[i]*v[i]);
    		mn[i]=mx[i]=v[i];
    		siz[i]=1;
    		fa[i]=id[i]=i;
    	}
    	sort(id+1,id+n+1,cmp);
    	for(int i=1;i<=n;i++){
    		int x=id[i];
    		z[x]=1;
    		if(z[x-1]) pt(x-1,x);
    		if(z[x+1]) pt(x+1,x);
    	}
    	printf("%llu",ans);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
  • 相关阅读:
    字符串函数(一)之常见用法
    29-Gin框架中间件详解
    OpenCV计算机视觉学习(15)——浅谈图像处理的饱和运算和取模运算
    git--工作区、暂存区、本地仓库、远程仓库
    go中如何处理error
    高校社团管理系统jsp和javabean开发
    CppLib v1.1 和 pexports v4.7 的下载链接记录
    华为OD机考算法题:字符串解密
    智慧社区管理系统:构建未来的生活模式
    【Java】DDD领域驱动设计理解
  • 原文地址:https://blog.csdn.net/tanjunming2020/article/details/133673383