zoukankan      html  css  js  c++  java
  • CF1313C Skyscrapers

    C. Skyscrapers

    原题传送门

    Problem Restatement

    第一行有一个整数 (n (1 leq n leq 500000)),表示发展商购买了 (n) 块地。

    第二行,(n) 个整数 (m_1, m_2, ldots, m_n (1 leq m_i leq 10^9)),表示每块地上建摩天大厦层数的限制。

    求让每块地上摩天大厦的楼层数之和最大,而且存在最高点(a_i),让它左边的楼递增,右边的楼递减。

    Solution

    (O(n^2))的做法就不赘述了。

    关键在于在遍历最高点的时候,如何快速计算出其左右两边依次递减之和。

    首先可以想到遍历用线段树维护区间和,然后二分找到上一个比该节点大的点,后面全部区间染色成(m[i])即可。复杂度(O(nlog^2n))。代码可参见Codeforces Submission

    然而实际上可以在构造线段树的同时,维护一个区间最大值,然后利用线段树自己的二分结构进行二分,同样区间染色。复杂度(o(nlogn))。这个代码我没写QAQ。

    不过思考能否不维护一个完整的序列,发现可以用单调栈来维护(i)前面的单调上升的栈,然后利用类似DP的思想,利用栈顶元素已经求好的前缀和外加区间染色后的和。均摊复杂度为(O(n))。代码如下。

    Code

    #include <bits/stdc++.h>
    #define LL long long
    #define MAXN 500005
    using namespace std;
    
    LL m[MAXN],ls[MAXN],rs[MAXN];
    stack<int> st;
    
    void solve(){
    	int n;
    	scanf("%d", &n);
    	for(int i=1;i<=n;i++)
    		scanf("%lld", &m[i]);
    	for(int i=1;i<=n;i++){
    		while(!st.empty() && m[st.top()]>m[i])
    			st.pop();
    		if(!st.empty()) ls[i]=ls[st.top()]+m[i]*(i-st.top());
    		else ls[i]=m[i]*i;
    		st.push(i);
    	}
    	st=stack<int>();
    	for(int i=n;i>=1;i--){
    		while(!st.empty() && m[i]<m[st.top()])
    			st.pop();
    		if(!st.empty()) rs[i]=rs[st.top()]+m[i]*(st.top()-i);
    		else rs[i]=m[i]*(n-i+1);
    		st.push(i);
    	}
    	LL mx=0,mi=0;
    	for(int i=n;i>=1;i--)
    		if(ls[i]+rs[i]-m[i]>mx)
    			mx=ls[i]+rs[i]-m[i], mi=i;
    	for(int i=mi-1;i>=1;i--)
    		m[i]=min(m[i],m[i+1]);
    	for(int i=mi+1;i<=n;i++)
    		m[i]=min(m[i],m[i-1]);
    	for(int i=1;i<=n;i++)
    		printf("%lld ", m[i]);
    }
    
    int main(){
    	int T=1;
    	// scanf("%d", &T);
    	while(T--){
    		solve();
    	}
    	return 0;
    }
    
  • 相关阅读:
    spider-抓取页面内容
    Zabbix监控
    时间戳转换
    计算机脱域
    查询指定时间内审核失败的事件日志
    spider-抓取网页内容(Beautiful soup)
    Queue
    spider-抓取网页内容
    MyEclipse+Tomcat配置
    Gradle Java Web应用程序并在Tomcat上运行
  • 原文地址:https://www.cnblogs.com/leachim/p/12388976.html
Copyright © 2011-2022 走看看