zoukankan      html  css  js  c++  java
  • [POI2008]砖块Klo

    Description
    N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次数的动作完成任务.

    Input
    第一行给出N,K. (1 ≤ k ≤ n ≤ 100000), 下面N行,每行代表这柱砖的高度.0 ≤ hi ≤ 1000000

    Output
    最小的动作次数

    Sample Input
    5 3
    3
    9
    2
    3
    1

    Sample Output
    2


    首先我简单讲一下题意,因为自己被坑过……
    有n个柱子,每次你可以给一个柱子高度+1或-1,要用最少的步数使得有k个连续的柱子一样高

    首先我们考虑k段,让这k个柱子到什么高度最优?对,中位数。

    所以我们弄一个可以维护区间中位数的数据结构来,记得要把前面小于中位数的和后面大于中位数的和求出来,统计答案要用

    /*program from Wolfycz*/
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define inf 0x7f7f7f7f
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')    f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x>=10)     print(x/10);
    	putchar(x%10+'0');
    }
    const int N=1e5;
    ll Ans=1e18;
    int V,L,R;
    struct Splay{
    	#define ls(x) tree[x][0]
    	#define rs(x) tree[x][1]
    	#define T(x) (rs(f[x])==x)
    	int tree[N+10][2],f[N+10],size[N+10],v[N+10],root,len;
    	ll sum[N+10];
    	void clear(int x){size[x]=ls(x)=rs(x)=f[x]=sum[x]=v[x]=0;}
    	void updata(int x){
    		size[x]=size[ls(x)]+size[rs(x)]+1;
    		sum[x]=sum[ls(x)]+sum[rs(x)]+v[x];
    	}
    	void move(int x){
    		int fa=f[x],son=tree[x][T(x)^1];
    		tree[x][T(x)^1]=fa;
    		tree[fa][T(x)]=son;
    		if (son)	f[son]=fa;
    		f[x]=f[fa];
    		if (f[x])	tree[f[x]][T(fa)]=x;
    		f[fa]=x;
    		updata(fa),updata(x);
    	}
    	void splay(int x){
    		while (f[x]){
    			if (f[f[x]])	T(x)==T(f[x])?move(f[x]):move(x);
    			move(x);
    		}
    		root=x;
    	}
    	void insert(int x){
    		v[++len]=x;
    		if (!root){
    			size[root=len]=1;
    			return;
    		}
    		int i=root;
    		while (true){
    			size[i]++,sum[i]+=x;
    			if (x<=v[i]){
    				if (!ls(i)){f[ls(i)=len]=i;break;}
    				i=ls(i);
    			}else{
    				if (!rs(i)){f[rs(i)=len]=i;break;}
    				i=rs(i);
    			}
    		}
    		splay(len);
    	}
    	int get_pre(){
    		int x=ls(root);
    		while (rs(x))	x=rs(x);
    		return x;
    	}
    	int get_suc(){
    		int x=rs(root);
    		while (ls(x))	x=ls(x);
    		return x;
    	}
    	int find(int i,int x){
    		if (!i)	return 0;
    		if (x==size[ls(i)]+1)	return i;
    		if (x<=size[ls(i)])	return find(ls(i),x);
    		return find(rs(i),x-size[ls(i)]-1);
    	}
    	bool work(int k){
    		splay(find(root,(k+1)>>1));
    		ll res=size[ls(root)]*v[root]-sum[ls(root)]+sum[rs(root)]-size[rs(root)]*v[root];
    		if (Ans>res){
    			Ans=res,V=v[root];
    			return 1;
    		}
    		return 0;
    	}
    	void Delete(int x){
    		splay(x);
    		if (!(ls(x)&&rs(x))){
    			f[root=ls(x)+rs(x)]=0;
    			clear(x);
    			return;
    		}
    		int i=get_pre();
    		splay(i);
    		f[rs(i)=rs(x)]=i;
    		clear(x);
    		updata(root);
    	}
    	int get_rank(int x){
    		int res=0;
    		for (int i=root;i;){
    			if (x<=v[i])	i=ls(i);
    			else	res+=size[ls(i)]+1,i=rs(i);
    		}
    		return res+1;
    	}
    	void Del(int x){Delete(find(root,get_rank(x)));}
    }T;
    int val[N+10];
    int main(){
    	int n=read(),k=read();
    	for (int i=1;i<=n;i++)	val[i]=read();
    	for (int i=1;i<=k;i++)	T.insert(val[i]);
    	for (int i=k+1;i<=n;i++){
    		if (T.work(k))	L=i-k,R=i-1;
    		T.Del(val[i-k]);
    		T.insert(val[i]);
    	}
    	if (T.work(k))	L=n-k+1,R=n;
    	printf("%lld
    ",Ans);
    //	for (int i=1;i<=n;i++)	printf("%d
    ",(L<=i&&i<=R)?V:val[i]);
    //原题要输出最后的状态,bzoj不用,故选择性注释掉
    	return 0;
    }
    
  • 相关阅读:
    站点被百度惩处应从哪些方面分析
    SVN 权限配置具体说明
    关于数组的应用
    实现键值对存储(二)——以现有键值对存储为模型
    大数据Lambda架构
    关于c++primer的一个代码错误
    怎样解决Ubuntu发热严重地问题
    【maven】pom.xml文件没错,但是项目有小红叉,Problems中可以看到错误:“Dynamic Web Module 3.0 requires Java 1.6 or newer.”
    【shiro】2.spring整合shiro,注解控制shiro用户/角色/权限And/OR,没有权限跳转到固定页面
    【shiro】使用shiro搭建的项目,页面引用js,报错:Uncaught SyntaxError: Unexpected token <
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/8954854.html
Copyright © 2011-2022 走看看