zoukankan      html  css  js  c++  java
  • [Codeforces Round #622 (Div. 2)]

    [Codeforces Round #622 (Div. 2)] - C2. Skyscrapers (hard version) (单调栈)

    C2. Skyscrapers (hard version)

    time limit per test

    3 seconds

    memory limit per test

    512 megabytes

    input

    standard input

    output

    standard output

    This is a harder version of the problem. In this version n≤500000n≤500000

    The outskirts of the capital are being actively built up in Berland. The company "Kernel Panic" manages the construction of a residential complex of skyscrapers in New Berlskva. All skyscrapers are built along the highway. It is known that the company has already bought nn plots along the highway and is preparing to build nn skyscrapers, one skyscraper per plot.

    Architects must consider several requirements when planning a skyscraper. Firstly, since the land on each plot has different properties, each skyscraper has a limit on the largest number of floors it can have. Secondly, according to the design code of the city, it is unacceptable for a skyscraper to simultaneously have higher skyscrapers both to the left and to the right of it.

    Formally, let's number the plots from 11 to nn. Then if the skyscraper on the ii-th plot has aiai floors, it must hold that aiai is at most mimi (1≤ai≤mi1≤ai≤mi). Also there mustn't be integers jj and kk such that j<i<kj<iaiai<ak. Plots jj and kk are not required to be adjacent to ii.

    The company wants the total number of floors in the built skyscrapers to be as large as possible. Help it to choose the number of floors for each skyscraper in an optimal way, i.e. in such a way that all requirements are fulfilled, and among all such construction plans choose any plan with the maximum possible total number of floors.

    Input

    The first line contains a single integer nn (1≤n≤5000001≤n≤500000) — the number of plots.

    The second line contains the integers m1,m2,…,mnm1,m2,…,mn (1≤mi≤1091≤mi≤109) — the limit on the number of floors for every possible number of floors for a skyscraper on each plot.

    Output

    Print nn integers aiai — the number of floors in the plan for each skyscraper, such that all requirements are met, and the total number of floors in all skyscrapers is the maximum possible.

    If there are multiple answers possible, print any of them.

    Examples

    input

    Copy

    5
    1 2 3 2 1
    

    output

    Copy

    1 2 3 2 1 
    

    input

    Copy

    3
    10 6 8
    

    output

    Copy

    10 6 6 
    

    Note

    In the first example, you can build all skyscrapers with the highest possible height.

    In the second test example, you cannot give the maximum height to all skyscrapers as this violates the design code restriction. The answer [10,6,6][10,6,6] is optimal. Note that the answer of [6,6,8][6,6,8] also satisfies all restrictions, but is not optimal.

    题意:

    给定一个整数n以及一个数组m。

    让你构建一个数组a满足:

    (1 le a_i le m_i),且不存在这样的情况(j < i < k,a_j > a_i < a_k)

    要求满足上述条件的同事,数组的sum和最大。

    思路:

    我们知道要满足数组的条件,数组必须是一个单峰数组。即我们只需要找到那个数组的峰值的下标即可。

    用单调栈维护两个数组:

    (pre[i])代表从1到(i) 单调不减时最大的前缀和。

    (suf[i])代表从(i)(n) 单调不升时最大的后缀和。

    那么我们找到(pre[i] + suf[i + 1])的最大值下标就是目标数组的峰值下标,然后输出答案即可。

    代码:

    const int maxn = 1000010;
    const int inf = 0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    int n;
    ll a[maxn];
    stack<pll> st;
    ll pre[maxn];
    ll suf[maxn];
    
    int main()
    {
    	//freopen("D:\code\text\input.txt","r",stdin);
    	//freopen("D:\code\text\output.txt","w",stdout);
    	n = readint();
    	repd(i, 1, n)
    	{
    		a[i] = readll();
    	}
    	ll sum = 0ll;
    	repd(i, 1, n)
    	{
    		pll temp = mp(a[i], 1ll);
    		while (!st.empty() && temp.fi <= st.top().fi)
    		{
    			pll now = st.top();
    			st.pop();
    			sum -= now.fi * now.se;
    			temp.se += now.se;
    		}
    		st.push(temp);
    		sum += temp.fi * temp.se;
    		pre[i] = sum;
    		// cout << pre[i] << " ";
    	}
    	// cout << endl;
    	while (!st.empty())
    	{
    		st.pop();
    	}
    	sum = 0ll;
    	for (int i = n; i >= 1; --i)
    	{
    		pll temp = mp(a[i], 1ll);
    		while (!st.empty() && temp.fi <= st.top().fi)
    		{
    			pll now = st.top();
    			st.pop();
    			sum -= now.fi * now.se;
    			temp.se += now.se;
    		}
    		st.push(temp);
    		sum += temp.fi * temp.se;
    		suf[i] = sum;
    		// cout << suf[i] << " ";
    	}
    	// cout << endl;
    	ll ans = 0ll;
    	int id;
    	repd(i, 0, n)
    	{
    		if (pre[i] + suf[i + 1] > ans)
    		{
    			ans = pre[i] + suf[i + 1];
    			id = i;
    		}
    	}
    	repd(i, id + 2, n)
    	{
    		a[i] = min(a[i], a[i - 1]);
    	}
    	for (int i = id - 1; i >= 1; --i)
    	{
    		a[i] = min(a[i], a[i + 1]);
    	}
    	repd(i, 1, n)
    	{
    		printf("%lld%c", a[i], i == n ? '
    ' : ' ');
    	}
    
    
    
    
    	return 0;
    }
    
    
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    Spring Cloud Alibaba Sentinel 服务限流降级
    干掉 Feign,Spring Cloud Square 组件发布
    Linux命令之free
    Java 导入excel获取表格信息
    [转] 阿里云服务器 liunx 安装配置 redis
    tomcat 动态日志查看
    linux服务器只部署了2个项目,却时常内存占满的问题解决路程
    电脑换了,重装了,配置了环境,然后重新导入项目, 结果爆红
    IDEA External libraries 不显示Maven中引入的repository
    linux 手动释放buff/cache
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/12358016.html
Copyright © 2011-2022 走看看