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

    传送门

    很显然看的出是中位数吧,那只要动态维护一下中位数和区间和就差不多了吧
    平衡树太难写,我选择权值线段树
    洛谷的这个题要输出方案,但是不打紧
    代码(bzoj):

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    void read(int &x) {
    	char ch; bool ok;
    	for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
    	for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
    }
    #define rg register
    const int maxn=1e5+10;
    int n,m,mx,a[maxn];long long ans=1e15;
    struct oo{int l,r,v;long long sum;}s[maxn*40];
    void build(int x,int l,int r)
    {
    	s[x].l=l,s[x].r=r;
    	if(l==r)return ;int mid=(l+r)>>1;
    	build(x<<1,l,mid),build(x<<1|1,mid+1,r);
    }
    void update(int x){s[x].sum=s[x<<1].sum+s[x<<1|1].sum,s[x].v=s[x<<1].v+s[x<<1|1].v;}
    void change(int x,int l,int v) 
    {
    	if(s[x].l==s[x].r){s[x].sum+=s[x].l*v,s[x].v+=v;return ;}
    	int mid=(s[x].l+s[x].r)>>1;
    	if(l<=mid)change(x<<1,l,v);else change(x<<1|1,l,v);
    	update(x);
    }
    int get(int x,int l)
    {
    	if(s[x].l==s[x].r)return s[x].l;
    	if(l<=s[x<<1].v)return get(x<<1,l);
    	else return get(x<<1|1,l-s[x<<1].v);
    }
    long long getans(int x,int l,int r)
    {
    	if(l>r)return 0;
    	if(l<=s[x].l&&r>=s[x].r)return s[x].sum;
    	long long ans=0;int mid=(s[x].l+s[x].r)>>1;
    	if(l<=mid)ans+=getans(x<<1,l,r);
    	if(r>mid)ans+=getans(x<<1|1,l,r);
    	return ans;
    }
    int getsum(int x,int l,int r)
    {
    	if(l>r)return 0;
    	if(l<=s[x].l&&r>=s[x].r)return s[x].v;
    	int mid=(s[x].l+s[x].r)>>1,ans=0;
    	if(l<=mid)ans+=getsum(x<<1,l,r);
    	if(r>mid)ans+=getsum(x<<1|1,l,r);
    	return ans;
    }
    int main()
    {
    	read(n),read(m);
    	for(rg int i=1;i<=n;i++)read(a[i]),mx=max(mx,a[i]);
    	build(1,0,mx+1);
    	for(rg int i=1;i<m;i++)change(1,a[i],1); 
    	for(rg int i=m;i<=n;i++)
    	{
    		change(1,a[i],1);int mid=get(1,m/2+1);
    		ans=min(ans,1ll*mid*getsum(1,0,mid)-getans(1,0,mid)+getans(1,mid,mx+1)-1ll*mid*getsum(1,mid,mx+1));
    		change(1,a[i-m+1],-1);
    	}
    	printf("%lld
    ",ans);
    }
    

    代码(luogu):

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    void read(int &x) {
    	char ch; bool ok;
    	for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
    	for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
    }
    #define rg register
    const int maxn=1e5+10;
    int n,m,mx,a[maxn],l,r,mn;long long ans=1e15;
    struct oo{int l,r,v;long long sum;}s[maxn*40];
    void build(int x,int l,int r)
    {
    	s[x].l=l,s[x].r=r;
    	if(l==r)return ;int mid=(l+r)>>1;
    	build(x<<1,l,mid),build(x<<1|1,mid+1,r);
    }
    void update(int x){s[x].sum=s[x<<1].sum+s[x<<1|1].sum,s[x].v=s[x<<1].v+s[x<<1|1].v;}
    void change(int x,int l,int v) 
    {
    	if(s[x].l==s[x].r){s[x].sum+=s[x].l*v,s[x].v+=v;return ;}
    	int mid=(s[x].l+s[x].r)>>1;
    	if(l<=mid)change(x<<1,l,v);else change(x<<1|1,l,v);
    	update(x);
    }
    int get(int x,int l)
    {
    	if(s[x].l==s[x].r)return s[x].l;
    	if(l<=s[x<<1].v)return get(x<<1,l);
    	else return get(x<<1|1,l-s[x<<1].v);
    }
    long long getans(int x,int l,int r)
    {
    	if(l>r)return 0;
    	if(l<=s[x].l&&r>=s[x].r)return s[x].sum;
    	long long ans=0;int mid=(s[x].l+s[x].r)>>1;
    	if(l<=mid)ans+=getans(x<<1,l,r);
    	if(r>mid)ans+=getans(x<<1|1,l,r);
    	return ans;
    }
    int getsum(int x,int l,int r)
    {
    	if(l>r)return 0;
    	if(l<=s[x].l&&r>=s[x].r)return s[x].v;
    	int mid=(s[x].l+s[x].r)>>1,ans=0;
    	if(l<=mid)ans+=getsum(x<<1,l,r);
    	if(r>mid)ans+=getsum(x<<1|1,l,r);
    	return ans;
    }
    int main()
    {
    	read(n),read(m);
    	for(rg int i=1;i<=n;i++)read(a[i]),mx=max(mx,a[i]);
    	build(1,0,mx+1);
    	for(rg int i=1;i<m;i++)change(1,a[i],1); 
    	for(rg int i=m;i<=n;i++)
    	{
    		change(1,a[i],1);int mid=get(1,m/2+1);
    		long long now=1ll*mid*getsum(1,0,mid)-getans(1,0,mid)+getans(1,mid,mx+1)-1ll*mid*getsum(1,mid,mx+1);
    		if(ans>now)ans=now,l=i-m+1,r=i,mn=mid;
    		change(1,a[i-m+1],-1);
    	}
    	printf("%lld
    ",ans);
    	for(rg int i=1;i<=n;i++)printf("%d
    ",(i>=l&&i<=r)?mn:a[i]);
    }
    
  • 相关阅读:
    创建Variant数组
    ASP与存储过程(Stored Procedures)
    FileSystemObject对象成员概要
    Kotlin 朱涛9 委托 代理 懒加载 Delegate
    Kotlin 朱涛 思维4 空安全思维 平台类型 非空断言
    Kotlin 朱涛7 高阶函数 函数类型 Lambda SAM
    Kotlin 朱涛16 协程 生命周期 Job 结构化并发
    Proxy 代理模式 动态代理 cglib MD
    RxJava 设计理念 观察者模式 Observable lambdas MD
    动态图片 Movie androidgifdrawable GifView
  • 原文地址:https://www.cnblogs.com/lcxer/p/10387273.html
Copyright © 2011-2022 走看看