zoukankan      html  css  js  c++  java
  • D. Yet Another Yet Another Task

    题:https://codeforces.com/contest/1359/problem/D

    题意:给定一个序列,你可以选择一个区间[L,R],你需要remove掉其中最大的,再sum{L,R},问最大可能是多少。

    分析:也就是说,我们可以枚举每个数ai作为最大值,然后再ai左边找前缀和最小的,在ai后边找前缀和最大的,这个用线段树可以实现(简单嘛,也可以用其他数据结构),关键是要在哪些区间选取是最大的,要保证当前ai最大只需要预处理:ai 最左能达到哪个位置使经过的位置的值都比ai小,就可以确定线段树选取的区间了,向右也是一样,这一部分用单调区间的做法即可。

    #include<bits/stdc++.h>
    using namespace std;
    #define pb push_back
    #define lson root<<1,l,midd
    #define rson root<<1|1,midd+1,r
    typedef long long ll;
    const int inf=0x3f3f3f3f;
    const ll INF=1e18;
    const int M=1e5+5;
    struct node{
        int mi,mx;
    }tr[M<<2];
    int a[M],l[M],r[M],sum[M];
    void up(int root){
        tr[root].mi=min(tr[root<<1].mi,tr[root<<1|1].mi);
        tr[root].mx=max(tr[root<<1].mx,tr[root<<1|1].mx);
    }
    void build(int root,int l,int r){
        if(l==r){
            tr[root].mi=tr[root].mx=sum[l];
            return ;
        }
        int midd=(l+r)>>1;
        build(lson);
        build(rson);
        up(root);
    }
    int querymi(int L,int R,int root,int l,int r){
        if(L<=l&&r<=R){
            return tr[root].mi;
        }
        int midd=(l+r)>>1;
        int res=inf;
        if(L<=midd)
            res=querymi(L,R,lson);
        if(R>midd)
            res=min(res,querymi(L,R,rson));
        return res;
    }
    int querymx(int L,int R,int root,int l,int r){
        if(L<=l&&r<=R){
            return tr[root].mx;
        }
        int midd=(l+r)>>1;
        int res=-inf;
        if(L<=midd)
            res=querymx(L,R,lson);
        if(R>midd)
            res=max(res,querymx(L,R,rson));
        return res;
    }
    int main(){
        int n;
        scanf("%d",&n);
        a[1]=0,n++;
        for(int i=0;i<=4*n;i++)
            tr[i].mi=inf,tr[i].mx=-inf;
        for(int i=2;i<=n;i++)
            scanf("%d",&a[i]),sum[i]=sum[i-1]+a[i];
        build(1,1,n);
        int ans=0;
        for(int i=2;i<=n;i++){
            l[i]=i;
            while(a[l[i]-1]<=a[i]&&l[i]-1>=2){
                l[i]=l[l[i]-1];
            }
        }
        for(int i=n;i>=2;i--){
            r[i]=i;
            while(a[r[i]+1]<=a[i]&&r[i]+1<=n){
                r[i]=r[r[i]+1];
            }
        }
        for(int i=2;i<=n;i++){
            int t1=querymi(l[i]-1,i-1,1,1,n);
            int t2=querymx(i,r[i],1,1,n);
            ans=max(ans,t2-t1-a[i]);
        }
        printf("%d
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    重温算法第一篇:冒泡排序
    服务器报警邮件发送到QQ邮箱,但是被系统拦截
    记录MongoDB常用查询
    一次 Mysql 字符集的报错,最后让我万马奔腾!!!
    Hbase 一次表异常,有一张表 无法count scan 一直显示重连
    spark编译安装 spark 2.1.0 hadoop2.6.0-cdh5.7.0
    有一些sql 是必须要做笔记的!!
    linux 修改openfiles
    在线HTTP POST/GET接口测试工具
    HBase 官方文档中文版
  • 原文地址:https://www.cnblogs.com/starve/p/13025595.html
Copyright © 2011-2022 走看看