zoukankan      html  css  js  c++  java
  • 某看起来会做的数据结构题

    P2659 美丽的序列

    题目背景

    GD是一个热衷于寻求美好事物的人,一天他拿到了一个美丽的序列。

    题目描述

    为了研究这个序列的美丽程度,GD定义了一个序列的“美丽度”和“美丽系数”:对于这个序列的任意一个区间[l,r],这个区间的“美丽度”就是这个区间的长度与这个区间的最小值的乘积,而整个序列的“美丽系数”就是它的所有区间的“美丽度”的最大值。现在GD想要你帮忙计算这个序列的“美丽系数”。

    输入输出格式

    输入格式:
    第一行一个整数n,代表序列中的元素个数。 第二行n个整数a1、a2„an,描述这个序列。

    输出格式:
    一行一个整数,代表这个序列的“美丽系数”。

    输入输出样例

    输入样例#1: 复制
    3
    1 2 3
    输出样例#1: 复制
    4
    说明

    样例解释 选取区间[2,3],可以获得最大“美丽系数”为2*2=4。 数据范围 对于20%的数据,n<=2000; 对于60%的数据,n<=200000; 对于100%的数据,1<=n<=2000000,0<=ai<=2000000。 提示 你可能需要一个读入优化。

    这个题目很熟悉
    以前接触过
    首先这是一个分治算法
    找出整段序列的最小值
    然后递归最小值两侧求解

    这个做法可以用线段树等结构维护
    然后还有一个比较简单的单调栈做法

    #include<iostream>
    #include<cstdio>
    #define N 20000005
    using namespace std;
    
    int anss;
    
    struct node{
        int l,r,s,pos;
    };
    
    struct segment{
        int n;
        node t[N];
        void PushUp(int ret){
            if(t[t[ret<<1].pos].s>t[t[ret<<1|1].pos].s)
                t[ret].pos=t[t[ret<<1].pos].s;
            else t[ret].pos=t[t[ret<<1|1].pos].s;
        }
        inline void Build(int l,int r,int ret){
            t[ret].l=l;t[ret].r=r;
            if(l==r){
                t[ret].pos=ret;
                anss=max(anss,t[ret].s);
                scanf("%d",&t[ret].s);
                return;
            }
            int mid=(l+r)>>1;
            Build(l,mid,ret<<1);
            Build(mid+1,r,ret<<1|1);
            PushUp(ret);
        }
        int Gmin(int a,int b){
            return t[a].s>t[a].s?a:b;
        }
        inline int query(int ret,int L,int R){
            int l=t[ret].l,r=t[ret].r;
            if(l>=L&&r<=R)
                return t[ret].pos;
            int mid=(l+r)>>1;
            int ans=0x7fffffff;
            if(R>mid)ans=Gmin(ans,query(ret<<1|1,L,R));
            if(L<=mid)ans=Gmin(ans,query(ret<<1,L,R));
            return ans;
        }
    }Now;
    
    int ans(int l,int r){
        if(l==r)return 0;
        int pos=Now.query(1,l,r);
        int minl=Now.t[pos].l;
        int ansl=0;
        ansl=max((r-l+1)*Now.t[pos].s,max(ans(l,minl-1),ans(minl+1,r)));
        return ansl;
    }
    int main(){
        int n,m;
        cin>>n>>m;
        Now.Build(1,n,1);
        printf("%d",ans(1,n));
        return 0;
    }
    
    
  • 相关阅读:
    hibernate.cfg.xml
    java util 巧用
    Ant
    WEB文件上传二 (Struts 文件上传)
    web文件上传一学习记录 (简单的web浏览器可读文件的上传,servlet 文件上传)
    long类型的时间转为n秒前n分钟前n小时前或者日期
    各种String类型的时间转long型,long转String
    Android 内容提供者(ContentProvider)的简单实用
    sql性能优化总结(转)
    数据添加到DataTable
  • 原文地址:https://www.cnblogs.com/qdscwyy/p/7875297.html
Copyright © 2011-2022 走看看