Histogram Sequence Gym - 102059J

题目传送门:[https://codeforces.com/gym/102059/problem/J](https://codeforces.com/gym/102059/problem/J)

题意: 给定一个直方图,一个长度为n的序列表示每个柱子的高度,有一个数组A记录着直方图中每个不同子矩形的面积,A数组是按从小到大排序好的,给你L和R,让你输出A[L]到A[R]。
思路:单调栈+二分+优先队列
首先用单调栈求出每个柱子往左右扩展的范围,然后二分A[L]处储存的面积大小,因为知道每个柱子的扩展范围后,可以计算有多少个不同子矩形的面积为相同的值,因此二分查找A[L],通过计算有多少不同个子矩形的面积小于等于该答案,来检查答案是否合法,找到一个面积值S, 使得小于等于S的子矩形个数大于等于L;记录下这个面积,然后通过将每个该面积大小的子矩形长度加一得到的面积存入优先队列,面积小的在前,从队首取出,检查该面积的子矩形是否存在,若存在,计算存在的数量,计入答案,直到数目到达R;
对于如何计算小于等于一个面积值的子矩形个数,有如下公式:

//
// Created by mile on 2019/7/29.
//
//gym 102059j
//二分+单调栈+优先队列

#include <bits/stdc++.h>

#define ps push
#define pb push_back
#define mp make_pair
using namespace std;
const int maxn = 300005;
typedef long long ll;

struct Node {
    ll id, h, w;
    Node() {}
    Node(ll a, ll b, ll c) : id(a), h(b), w(c) {}
    bool operator < (const Node& a) const {
        return h*w > a.h*a.w;
    }
};

struct Histogram {
    ll n, L, R, sumlen, h[maxn], l[maxn], r[maxn], st[maxn];

    ll init(int n) {
        this->n = n;
        sumlen = 0;
        for(int i = 1; i <= n; i++) scanf("%I64d", &h[i]), sumlen += h[i], l[i] = 1, r[i] = n;
        scanf("%I64d%I64d", &L, &R);
        int tail = 0;
        for(int i = 1; i <= n+1; i++) {
            while (tail >= 1 && h[st[tail]] > h[i]) {
                r[st[tail]] = i-1;
                l[i] = l[st[tail]];
                tail--;
            }
            if(tail) l[i] = st[tail]+1;
            st[++tail] = i;
        }
    }

    ll getnum(ll x, ll y) {
        x = max(1ll, y-x+1);
        return (y+x)%2 == 0 ? (y+x)/2*(y-x+1) : (y-x+1)/2*(y+x);
    }

    ll getlen(ll x, ll y, ll z, ll len) {
        return max(0ll, z-y-len+2)-max(0ll, z-x-len+1)-max(0ll, x-y-len+1);
    }

    ll solve(ll x) {
        ll sum = 0;
        for(int i = 1; i <= n; i++) {
            if(h[i] > x) continue;
            ll len = r[i]-l[i]+1;
            sum += getnum(x/h[i], len)-getnum(x/h[i], r[i]-i)-getnum(x/h[i], i-l[i]);
        }
        return sum;
    }

    ll binary_search(ll L, ll& ans) {
        ll lr = 1, rr = sumlen;
        while(lr < rr) {
            long long mid = (lr+rr)>>1;
            long long val = solve(mid);
            if(val < L) {
                lr = mid+1;
            } else {
                rr = mid;
            }
        }
        ans = lr;
        return solve(lr);
    }

    void work() {
        ll ans = 0;
        ll tmp = binary_search(L, ans);
        while(L <= R && L <= tmp) {
            printf("%I64d ", ans);
            L++;
        }
        priority_queue<Node> Q;
        for(int i = 1; i <= n; i++) Q.ps(Node(i, h[i], ans/h[i]+1));
        Node nxt;
        while(L <= R) {
            nxt = Q.top();
            Q.pop();
=            if(nxt.id >= 300005 || nxt.id <= 0) break;
            ll tlen = getlen(nxt.id, l[nxt.id], r[nxt.id], nxt.w);
            if(!tlen) continue;
            while(tlen > 0 && L <= R) {
                printf("%I64d ", nxt.h*nxt.w);
                tlen--;
                L++;
            }
            ++nxt.w;
            Q.ps(nxt);
        }
    }
};
Histogram ac;

int main()
{
    ll n;
    scanf("%I64d", &n);
    ac.init(n);
    ac.work();
    return 0;
}

原文地址:https://www.cnblogs.com/mile-star/p/11267226.html

时间: 2024-10-08 20:38:07

Histogram Sequence Gym - 102059J的相关文章

烟雾检测笔记1--《Video-based smoke detection with histogram sequence of LBP and LBPV pyramids》解析、实现

基于HEP(histograms of equivalent patterns[1])框架下的特征具有良好的纹理分类效果,LBP(local binary patterns[2])属于HEP框架下最常用的特征,具有对亮度.旋转等良好的不变特性.在基于分块的视频烟雾检测中,常使用其作为纹理分类的特征.然而,分块的图像具有局部性.这篇文章主要提出使用图像金字塔的方法让提取的烟雾块特征具有一定的全局属性.它将待检测烟雾块构成3级的金字塔,再对金字塔每一级提取不同模式的LBP特征,构成一个直方图序列作为

人脸识别必读的N篇文章

一,人脸检测/跟踪 人脸检测/跟踪的目的是在图像/视频中找到各个人脸所在的位置和大小:对于跟踪而言,还需要确定帧间不同人脸间的对应关系. 1, Robust Real-time Object Detection. Paul Viola, Michael Jones. IJCV 2004. 入选理由: Viola的人脸检测工作使得人脸检测真正变得实时可用.他们发表了一系列文章,这篇是引用率最高的一篇. 2, Fast rotation invariant multi-view face detec

人脸文章与数据库

作者:风雨兼程链接:https://zhuanlan.zhihu.com/p/22591740来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 一.人脸检测/跟踪 人脸检测/跟踪的目的是在图像/视频中找到各个人脸所在的位置和大小:对于跟踪而言,还需要确定帧间不同人脸间的对应关系. 1.Robust Real-time Object Detection. Paul Viola, Michael Jones. IJCV 2004. 入选理由: Viola的人脸检测工作使

Codeforces GYM 100114 C. Sequence 打表

C. Sequence Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Description Integer sequences are very interesting mathematical objects. Let us examine a sequence generated with the use of two operations: doubling and “digit

Gym 240084E - Correct Bracket Sequence Editor - [线段树]

题目链接:https://codeforces.com/gym/240084/problem/E 题意: 给出一个已经匹配的括号串,给出起始的光标位置(光标总是指向某个括号). 有如下操作: 1.往左移动一下光标: 2.往左移动一下光标: 3.删除当前光标指向的括号,以及和它匹配的那个括号,以及这两个括号之间的所有括号. 要求你给出在做完所有操作后的括号串. 题解: 用线段树维护,每个括号是否存在,存在记为 $1$,被删掉了记为 $0$. 然后我们只需要实现:①区间求和.②区间赋值.③根据 $k

(单调栈)poj-2559 Largest Rectangle in a Histogram

A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rectangles have equal widths but may have different heights. For example, the figure on the left shows the histogram that consists of rectangles with the

HDU 1056 Largest Rectangle in a Histogram(dp)(求最大的矩形面积)

Problem Description A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rectangles have equal widths but may have different heights. For example, the figure on the left shows the histogram that consists of

HDU 1506 Largest Rectangle in a Histogram (dp左右处理边界的矩形问题)

E - Largest Rectangle in a Histogram Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 1506 Appoint description: Description A histogram is a polygon composed of a sequence of rectangles aligned a

POJ 2559 Largest Rectangle in a Histogram(单调栈)

[题目链接]:click here~~ [题目大意]: A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rectangles have equal widths but may have different heights. For example, the figure on the left shows the histogram that con