zoukankan      html  css  js  c++  java
  • codeforces 817 D. Imbalanced Array(单调栈+思维)

    题目链接:http://codeforces.com/contest/817/problem/D

    题意:给你n个数a[1..n]定义连续子段imbalance值为最大值和最小值的差,要你求这个数组的imbalance总值

    题解:首先要知道imbalance的值可以有所有区间的Max的和减去所有区间Min的和。那么就是怎么求所有区间的Max和与Min和。要知道如果是以a[i]为最小值那么最小值为a[i]的区间数为a[i]左边第一个小于a[i]的位置l,a[i]右边第一个大于等于a[i]的位置r,ans=r*l*a[i]。然后就是怎么快速求解。这里可以利用一下单调栈的思想。具体看一下代码。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    typedef long long ll;
    const int M = 1e6 + 10;
    ll a[M] , dpl_Max[M] , dpl_Min[M] , dpr_Max[M] , dpr_Min[M];
    int main() {
        int n;
        scanf("%d" , &n);
        for(int i = 1 ; i <= n ; i++) scanf("%lld" , &a[i]);
        dpl_Max[1] = 0 , dpl_Min[1] = 0;
        for(int i = 2 ; i <= n ; i++) {
            dpl_Max[i] = dpl_Min[i] = i - 1;
            while(dpl_Max[i] >= 1 && a[dpl_Max[i]] < a[i]) dpl_Max[i] = dpl_Max[dpl_Max[i]];
            while(dpl_Min[i] >= 1 && a[dpl_Min[i]] > a[i]) dpl_Min[i] = dpl_Min[dpl_Min[i]];
        }
        dpr_Max[n] = n + 1 , dpr_Min[n] = n + 1;
        for(int i = n - 1 ; i >= 1 ; i--) {
            dpr_Max[i] = dpr_Min[i] = i + 1;
            while(dpr_Max[i] <= n && a[dpr_Max[i]] <= a[i]) dpr_Max[i] = dpr_Max[dpr_Max[i]];
            while(dpr_Min[i] <= n && a[dpr_Min[i]] >= a[i]) dpr_Min[i] = dpr_Min[dpr_Min[i]];
        }
        ll Sum_Max = 0 , Sum_Min = 0;
        for(int i = 1 ; i <= n ; i++) {
            Sum_Max += a[i] * (i - dpl_Max[i]) * (dpr_Max[i] - i);
            Sum_Min += a[i] * (i - dpl_Min[i]) * (dpr_Min[i] - i);
        }
        printf("%lld
    " , Sum_Max - Sum_Min);
        return 0;
    }
    
  • 相关阅读:
    UITabBarController生命周期(使用storyoard搭建)
    ios应用数据存储方式(归档)
    ios应用数据存储方式(偏好设置)
    使用picker View控件完成一个简单的选餐应用
    ios应用数据存储方式(XML属性列表-plist)
    控制器的View的创建
    控制器的创建
    权限管理具体代码实现
    gitHub相关
    初始Ajax
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/7071630.html
Copyright © 2011-2022 走看看