• Histogram Sequence Gym


    题目传送门:[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;
    }
    View Code
  • 相关阅读:
    SpringMVC使用ResponseEntity实现文件下载,及图片base64的字节数组上传于下载
    File类的createNewFile()和mkdirs() mkdir()
    为什么Java里的Arrays.asList不能用add和remove方法?
    java如何向数组里添加元素
    java里getPath、 getAbsolutePath、getCanonicalPath的区别
    MultipartFile 类
    File类的createNewFile()与createTempFile()的区别
    IntelliJ Idea解决Could not autowire. No beans of 'xxxx' type found的错误提示
    FileInputStream读取的两种方法:逐字节读;以字节数组读取
    JCE cannot authenticate the provider BC
  • 原文地址:https://www.cnblogs.com/mile-star/p/11267226.html
Copyright © 2020-2023  润新知