zoukankan      html  css  js  c++  java
  • BZOJ1592 POJ3666 [Usaco2008 Feb]Making the Grade 路面修整 左偏树 可并堆

    欢迎访问~原文出处——博客园-zhouzhendong

    去博客园看该题解


    题目传送门 - POJ3666

    题目传送门 - BZOJ1592


    题意概括

      整条路被分成了N段,N个整数A_1, ... , A_N (1 <= N <= 2,000)依次描述了每一段路的高度(0 <= A_i <= 1,000,000,000)。FJ希望找到一个恰好含N个元素的不上升或不下降序列B_1, ... , B_N,作为修过的路中每个路段的高度。由于将每一段路垫高或挖低一个单位的花费相同,修路的总支出可以表示为: |A_1 - B_1| + |A_2 - B_2| + ... + |A_N - B_N| 请你计算一下,FJ在这项工程上的最小支出是多少。FJ向你保证,这个支出不会超过2^31-1。


    题解

      和这个差不多。

      只需要做一次之后把原序列翻转再做一次就可以了。

      不用-i,因为这次是非递增或者非递减。


    代码

    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    using namespace std;
    typedef long long LL;
    const int N=1000005;
    int n,v[N],root[N],L[N],R[N],top;
    int ls[N],rs[N],npl[N],size[N],val[N];
    void make_heap(int x,int v){
    	ls[x]=rs[x]=npl[x]=0,val[x]=v,size[x]=1;
    }
    int merge(int a,int b){
    	if (1LL*a*b==0)
    		return a+b;
    	if (val[a]<val[b])
    		swap(a,b);
    	rs[a]=merge(rs[a],b);
    	if (npl[rs[a]]>npl[ls[a]])
    		swap(rs[a],ls[a]);
    	npl[a]=npl[rs[a]]+1;
    	size[a]=size[ls[a]]+size[rs[a]]+1;
    	return a;
    }
    void pop(int &x){
    	x=merge(ls[x],rs[x]);
    }
    int main(){
    	scanf("%d",&n);
    	for (int i=1;i<=n;i++)
    		scanf("%d",&v[i]);
    	LL ans=1LL<<50;
    	for (int cc=0;cc<2;cc++){
    		top=0;
    		for (int i=1;i<=n;i++){
    			make_heap(root[++top]=i,v[i]);
    			L[top]=R[top]=i;
    			while (top>1&&val[root[top-1]]>val[root[top]]){
    				top--;
    				root[top]=merge(root[top],root[top+1]);
    				R[top]=R[top+1];
    				while (size[root[top]]*2>R[top]-L[top]+2)
    					pop(root[top]);
    			}
    		}
    		LL ans1=0;
    		for (int i=1;i<=top;i++)
    			for (int j=L[i];j<=R[i];j++)
    				ans1+=abs(val[root[i]]-v[j]);
    		ans=min(ans,ans1);
    		for (int i=1;i<=n/2;i++)
    			swap(v[i],v[n+1-i]);
    	}
    	printf("%lld",ans);
    	return 0;
    } 
    

      

  • 相关阅读:
    POJ 3683 Priest John&#39;s Busiest Day (2-SAT+输出可行解)
    Codeforces #2B The least round way(DP)
    避免死锁的银行家算法C++程序实现
    源代码编译安装MySQL5.6.12具体过程
    Android 设计模式
    Java与设计模式-适配器模式
    Java和Flex整合报错(五)
    三层架构—再思考
    怎样让DBGrid在按住Shift点鼠标的同时能将连续范围的多行选中?
    找出你的短板
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/BZOJ1592.html
Copyright © 2011-2022 走看看