首页 > 其他分享 >codeforces-817 D. Imbalanced Array(单调栈)

codeforces-817 D. Imbalanced Array(单调栈)

时间:2023-07-13 11:45:16浏览次数:41  
标签:int top codeforces pop while 最小值 Imbalanced Array empty

image

题意:求数组中每个连续子序列的的最大值-最小值之和。
思路:题意可以理解为加上每一个序列的最大值,减去每一个序列的最小值。每个数都可以作为某一连续子序列的最大值和最小值,所以可以枚举每一个数作为最值的区间,暴力枚举时间复杂度过高,所以利用单调栈找出每个数左边或右边第一个比本身小的数,这样该数就是区间中最小的数。同理也可以找该数为最大数的区间。这里有个坑就是有可能答案会算重复。比如1 4 1,第一个1最为最小值的时候会算一个1 4 1,第三个1最为最小值的时候也会算一个1 4 1。只有我们用单调栈来求L【i】的时候保持左开右闭就可以保证只算一次。

点击查看代码
#include<bits/stdc++.h>
using namespace std;

const int N = 1e6+100;
int a[N],l[N],r[N];
stack<int> s;

int main(){
    ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
    int n;
    long long ans = 0;
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=1;i<=n;i++){
        while(!s.empty()&&a[s.top()]>a[i]) s.pop();
        if(s.empty()) l[i] = 1;
        else l[i] = s.top() + 1;
        s.push(i);
    }
    while(!s.empty())
        s.pop();
    for(int i=n;i>=1;i--){
        while(!s.empty()&&a[s.top()]>=a[i]) s.pop();
        if(s.empty()) r[i] = n;
        else r[i] = s.top() - 1;
        s.push(i);
    }
    while(!s.empty())
        s.pop();
    for(int i=1;i<=n;i++)
        ans -= 1LL * (i - l[i] + 1) * (r[i] - i + 1) * a[i];

    for(int i=1;i<=n;i++){
        while(!s.empty()&&a[s.top()]<a[i]) s.pop();
        if(s.empty()) l[i] = 1;
        else l[i] = s.top() + 1;
        s.push(i);
    }
    while(!s.empty())
        s.pop();
    for(int i=n;i>=1;i--){
        while(!s.empty()&&a[s.top()]<=a[i]) s.pop();
        if(s.empty()) r[i] = n;
        else r[i] = s.top() - 1;
        s.push(i);
    }
    for(int i=1;i<=n;i++)
        ans += 1LL * (i - l[i] + 1) * (r[i] - i + 1) * a[i];
    cout<<ans<<'\n';
    return 0;
}

标签:int,top,codeforces,pop,while,最小值,Imbalanced,Array,empty
From: https://www.cnblogs.com/kingqiao/p/17547186.html

相关文章

  • Codeforces Round 871 (Div. 4) ABCDEF
    很久没写题目了,划点水题A.LoveStory#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;typedefpair<LL,LL>PII;constLLMAXN=1e18;constLLN=1e6,M=4002;constLLmod=1e9+7;intmain(){//cin.tie(0);cout.tie(0);ios......
  • Java复制(拷贝)数组的4种方法:arraycopy()方法、clone() 方法、copyOf()和copyOfRange
    http://c.biancheng.net/view/924.html所谓复制数组,是指将一个数组中的元素在另一个数组中进行复制。本文主要介绍关于 Java 里面的数组复制(拷贝)的几种方式和用法。在Java中实现数组复制分别有以下4种方法:Arrays类的copyOf()方法Arrays类的copyOfRange()方法Syst......
  • 「解题报告」Codeforces Round #884 (Div. 1 + Div. 2) Editorial
    比赛地址:Dashboard-CodeforcesRound884(Div.1+Div.2)-Codeforces个人评价:这场是构造专场!A.SubtractionGameProblem-A-Codeforces有一堆石子(应该是石子),每次只能拿走\(a\)块或者\(b\)块,最先不能移动的人输,构造一个数\(n\),使得先手必输。两种构造方法:......
  • SystemVerilog Dynamic Array Randomization
    https://verificationguide.com/systemverilog/systemverilog-dynamic-array-randomization/DynamicArrayRandomizeForadynamicarray,itispossibletorandomizebotharraysizeandarrayelements.randomizedynamicarraysizeInbelowexample,dynamicarr......
  • CodeForces Gym 102900B Mine Sweeper II
    CF传送门感觉像脑筋急转弯。考虑所有数字之和就是相邻的\((\text{雷},\text{空地})\)对数,因此翻转后这个对数不会改变。然后由于抽屉原理,\(b\toa\)和\(b\to\operatorname{inv}(a)\)中至少有一个操作次数\(\le\left\lfloor\frac{nm}{2}\right\rfloor\),然后就做完了......
  • Codeforces Round #771 (Div. 2) A-E
    A代码#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;intp[507];boolsolve(){intn;cin>>n;for(inti=1;i<=n;i++)cin>>p[i];intpos1=0,pos2=0;for(inti=1;i<=n;i++){......
  • CodeForces 1525F Goblins And Gnomes
    洛谷传送门CF传送门套路地,将DAG的最小不交路径覆盖转化为点数减去拆点以后最大匹配。感性理解就是一开始每个点都是一条路径,一个匹配意味着两条路径结合了。由题意知,第\(i\)次进攻时最小不交路径覆盖必须\(>i\),也就是说,设最大匹配为\(k\),那么\(n-k>i\),即\(k\le......
  • E. Two Chess Pieces -- (codeforces) 树形DP
    原题链接:https://codeforces.com/contest/1774/problem/E题意:两颗棋子,给出两颗棋子必须要去的顶点,且给出两颗棋子的相隔距离不能大于d,算出两颗棋子完成目标后走的距离。最后两颗棋子都要回到顶点1上。思路:刚开始没想出来,顺着官方题解写的,大意就是我用数组s1和s2代表两颗棋子......
  • Qt QJsonDocument以及与QJsonArray、QJsonObject、QJsonValue的关联
    0、说明QJsonDocument类提供了read/writeJSON文档的方法。用QJsonDocument::fromJson()方法,可以从将一个JSON文件(或者QByteArray数据)转换为QJsonDocument,用QJsonDocument::toJson()则能起到相反的用法。在此过程中的语法解析是很高效的,并且可以将JSON转换为Qt使用的二......
  • CodeForces 1508C Complete the MST
    洛谷传送门AtCoder传送门比较需要观察的题。设\(v\)为所有边权异或和。直觉是设一条未确定权值的边边权为\(v\),其他的为\(0\)最优。证明大概就是讨论MST是否全部使用未确定权值的边。若全使用了,那么根据\(\oplusw\le\sumw\)可知\(\min\sumw=\oplusw\),并且......