zoukankan      html  css  js  c++  java
  • 【POJ 3658】Artificial Lake

    Artificial Lake
    Time Limit: 3000MS   Memory Limit: 65536K
    Total Submissions: 1862   Accepted: 625

    Description

    The oppressively hot summer days have raised the cows' clamoring to its highest level. Farmer John has finally decided to build an artificial lake. For his engineering studies, he is modeling the lake as a two-dimensional landscape consisting of a contiguous sequence of N soon-to-be-submerged levels (1 ≤ N ≤ 100,000) conveniently numbered 1..N from left to right.

    Each level i is described by two integers, its width Wi (1 ≤ Wi ≤ 1,000) and height (like a relative elevation) Hi (1 ≤ Hi ≤ 1,000,000). The heights of FJ's levels are unique. An infinitely tall barrier encloses the lake's model on the left and right. One example lake profile is shown below.

                
    
    * * :
    * * :
    * * 8
    * *** * 7
    * *** * 6
    * *** * 5
    * ********** 4 <- height
    * ********** 3
    *************** 2
    *************** 1
    Level | 1 |2| 3 |

    In FJ's model, he starts filling his lake at sunrise by flowing water into the bottom of the lowest elevation at a rate of 1 square unit of water per minute. The water falls directly downward until it hits something, and then it flows and spreads as room-temperature water always does. As in all good models, assume that falling and flowing happen instantly. Determine the time at which each elevation's becomes submerged by a single unit of water.


    WATER WATER OVERFLOWS
    | |
    * | * * | * * *
    * V * * V * * *
    * * * .... * *~~~~~~~~~~~~*
    * ** * *~~~~** : * *~~~~**~~~~~~*
    * ** * *~~~~** : * *~~~~**~~~~~~*
    * ** * *~~~~**~~~~~~* *~~~~**~~~~~~*
    * ********* *~~~~********* *~~~~*********
    *~~~~********* *~~~~********* *~~~~*********
    ************** ************** **************
    ************** ************** **************

    After 4 mins After 26 mins After 50 mins
    Lvl 1 submerged Lvl 3 submerged Lvl 2 submerged

    Warning: The answer will not always fit in 32 bits.

    Input

    * Line 1: A single integer: N
    * Lines 2..N+1: Line i+1 describes level i with two space-separated integers: Wi and Hi

    Output

    * Lines 1..N: Line i contains a single integer that is the number of minutes that since sunrise when level #i is covered by water of height 1.

    Sample Input

    3
    4 2
    2 7
    6 4
    

    Sample Output

    4
    50
    26
    
    

    Source

     
    这道题其实是一道不是纯属意义的模拟。
    从最低的平台开始注水,然后向上一直灌,有太多情况了,我们甚至无法判断。
    我们可以倒过来想,我们是可以知道水位灌满达到最高的平台的高度+1的时候的体积(即时间)。
    然后我们记录这个答案,把这个大区间从此处断开分成两个小区间,然后先处理远离最低平台(即注水处)的那个区间,反复进行此过程即可。
    找最高的平台我们可以用RMQ预处理。
    时间复杂度O(Nlog2N)。
    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    
    const int MAXN = 100005;
    
    int n;
    int d[MAXN][17], num[MAXN][17], w[MAXN], h[MAXN];
    int _high, _num, mint, minn;
    long long sum[MAXN];
    long long ans[MAXN];
    long long t;
    
    void init()
    {
        sum[0] = w[0] = 0;
        mint = 0x7fffffff;
        for (int i = 1; i <= n; ++i) sum[i] += sum[i - 1];
        for (int i = 1; i <= n; ++i) w[i] += w[i - 1];
        for (int i = 1; i <= n; ++i)
            if (mint > h[i])
            {
                mint = h[i];
                minn = i;
            }
        for (int j = 1; (1 << j) <= n; ++j)
            for (int i = 1; i + (1 << (j - 1)) <= n; ++i)
            {
                int other = d[i + (1 << (j - 1))][j - 1];
                if (d[i][j - 1] < other)
                {
                    d[i][j] = other;
                    num[i][j] = num[i + (1 << (j - 1))][j - 1];
                }
                else
                {
                    d[i][j] = d[i][j - 1];
                    num[i][j] = num[i][j - 1];
                }
            }
    }
    
    void findout(int L, int R)
    {
        if (L == R)
        {
            _high = h[L];
            _num = L;
            return;
        }
        int k = 0;
        while ((1 << (k + 1)) <= (R - L + 1)) k++;
        if (d[L][k] > d[R - (1 << k) + 1][k])
        {
            _high = d[L][k];
            _num = num[L][k];
        }
        else
        {
            _high = d[R - (1 << k) + 1][k];
            _num = num[R - (1 << k) + 1][k];
        }
    }
    
    int abs(int x)
    {
        return x < 0 ? -x : x;
    }
    
    void solve(int l, int r, int lasth)
    {
        if (l > r) return;
        findout(l, r);
        t -= (long long)(w[r] - w[l - 1]) * (long long)(lasth - h[_num] - 1);
        ans[_num] = t;
        t -= w[r] - w[l - 1];
        int tnum = _num, thigh = _high;
        if (l <= minn && minn <= tnum - 1)
        {
            solve(tnum + 1, r, thigh);
            solve(l, tnum - 1, thigh);
        }
        else if (tnum + 1 <= minn && minn <= r)
            {
                solve(l, tnum - 1, thigh);
                solve(tnum + 1, r, thigh);
            }
            else
            if (abs(l - minn) > abs(r - minn))
            {
                solve(l, tnum - 1, thigh);
                solve(tnum + 1, r, thigh);
            }
            else
            {
                solve(tnum + 1, r, thigh);
                solve(l, tnum - 1, thigh);
            }
    }
    
    int main()
    {
        scanf("%d", &n);
        memset(d, 0, sizeof(d));
        for (int i = 1; i <= n; ++i)
        {
            scanf("%d%d", &w[i], &h[i]);
            d[i][0] = h[i];
            num[i][0] = i;
            sum[i] = (long long)w[i] * h[i];
        }
        init();
        findout(1, n);
        t = (long long)w[n] * (long long)(_high + 1) - sum[n];
        solve(1, n, _high + 1);
        for (int i = 1; i <= n; ++i) printf("%I64d
    ", ans[i]);
        return 0;
    }
  • 相关阅读:
    mount命令以及mount ntfs硬盘权限权限与显示的问题 分类: shell ubuntu 2014-11-08 18:29 148人阅读 评论(0) 收藏
    Rebuild my Ubuntu 分类: ubuntu shell 2014-11-08 18:23 193人阅读 评论(0) 收藏
    摄像头参数查看与调节 分类: C/C++ OpenCV 2014-11-08 18:13 138人阅读 评论(0) 收藏
    highgui.h备查 分类: C/C++ OpenCV 2014-11-08 18:11 292人阅读 评论(0) 收藏
    const char*, char const* and char *const 分类: C/C++ OpenCV 2014-11-08 18:10 114人阅读 评论(0) 收藏
    由 argv引出的main参数 分类: C/C++ 2014-11-08 18:00 154人阅读 评论(0) 收藏
    写在新建博客的第一天 分类: fool_tree的笔记本 2014-11-08 17:57 144人阅读 评论(0) 收藏
    Latex笔记(参考文献) 分类: LaTex 2014-11-08 17:41 239人阅读 评论(0) 收藏
    windows下使用github
    C# 笔记——索引器
  • 原文地址:https://www.cnblogs.com/albert7xie/p/4802178.html
Copyright © 2011-2022 走看看