zoukankan      html  css  js  c++  java
  • BZOJ 1112 线段树

    思路:
    权值线段树 (找中位数用的) 记录下出现的次数和sum

    一定要注意 有可能中位数的值有许多数 这怎么办呢 (离散化以后不去重就行了嘛…….)
    (为什么他们想得那么麻烦)

    //By SiriusRen
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define N 100500
    #define int long long
    int n,k,sum[N*10],tree[N*10],xx,ans=100000LL*1000000LL;
    struct Node{
        int num,pos;
        friend bool operator < (Node a,Node b){
            if(a.num!=b.num)return a.num<b.num;
            return a.pos<b.pos;
        }
    }node[N],cpy[N];
    void insert(int l,int r,int pos,int wei,int num){
        if(l==r){
            tree[pos]+=wei;
            if(tree[pos])sum[pos]=cpy[l].num;
            else sum[pos]=0;
            return;
        }
        int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
        if(mid>=num)insert(l,mid,lson,wei,num);
        else insert(mid+1,r,rson,wei,num);
        tree[pos]=tree[lson]+tree[rson];
        sum[pos]=sum[lson]+sum[rson];
    }
    void query(int l,int r,int pos,int num){
        if(l==r){xx=l;return;}
        int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
        if(tree[lson]>=num)query(l,mid,lson,num);
        else query(mid+1,r,rson,num-tree[lson]);
    }
    int query_sum(int l,int r,int pos,int L,int R){
        if(l>=L&&r<=R)return sum[pos];
        int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
        if(mid<L)return query_sum(mid+1,r,rson,L,R);
        else if(mid>=R)return query_sum(l,mid,lson,L,R);
        else return query_sum(l,mid,lson,L,R)+query_sum(mid+1,r,rson,L,R);
    }
    signed main(){
        scanf("%lld%lld",&n,&k);
        for(int i=1;i<=n;i++)
            scanf("%lld",&node[i].num),node[i].pos=i,cpy[i]=node[i];
        sort(cpy+1,cpy+1+n);
        for(int i=1;i<k;i++)
            insert(1,n,1,1,lower_bound(cpy+1,cpy+1+n,node[i])-cpy);
        for(int i=k;i<=n;i++){
            int temp=0;
            insert(1,n,1,1,lower_bound(cpy+1,cpy+1+n,node[i])-cpy);
            query(1,n,1,k/2+1);
            temp=cpy[xx].num*(k/2+1)-query_sum(1,n,1,1,xx);
            temp+=query_sum(1,n,1,xx+1,n)-cpy[xx].num*(k-(k/2+1));
            ans=min(ans,temp);
            insert(1,n,1,-1,lower_bound(cpy+1,cpy+1+n,node[i-k+1])-cpy);
        }
        printf("%lld
    ",ans);
    }

    这里写图片描述

  • 相关阅读:
    11.枚举类.md
    10. Lambda表达式.md
    9.内部类
    8.抽象类、接口和多态.md
    7.final关键字.md
    jQuery学习笔记(5)-事件与事件对象
    Log4Net学习笔记(1)-完整的例子
    SqlServer知识点-操作xml
    NHibernate常见错误汇总(0)-持续更新中
    jQuery学习笔记(4)-设置元素的属性和样式
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532170.html
Copyright © 2011-2022 走看看