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

    bzoj1112[POI2008]砖块Klo

    题意:

    N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:丢掉某柱砖的一块砖。给某柱加上一块砖,现在希望用最小次数的动作完成任务。N≤100000

    题解:

    设一个区间长度为k,其中位数为a,比a小的元素个数为b,和为c;比a大的元素个数为d,和为e。则题目要求维护一个长度为k的滑动窗口,能求出它的b*a-c+e-d*a。故用一个维护sum,size两个值的treap来维护。然而似乎我想复杂了?比所有人代码都大1k!注意要开long long。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <cstdlib>
     5 #define inc(i,j,k) for(int i=j;i<=k;i++)
     6 #define maxn 100010
     7 #define ll long long
     8 #define qs(x,y) qs(x,y)
     9 #define qb(x,y) qb(x,y)
    10 #define qss(x,y) qss(x,y)
    11 #define qbs(x,y) qbs(x,y)
    12 using namespace std;
    13 
    14 inline int read(){
    15     char ch=getchar(); int f=1,x=0;
    16     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    17     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    18     return f*x;
    19 }
    20 int ch[maxn][2],sz[maxn],cnt[maxn],rnd[maxn],n,k,tot,root; ll a[maxn],sm[maxn],v[maxn],ans;
    21 void update(int x){sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+cnt[x],sm[x]=sm[ch[x][0]]+sm[ch[x][1]]+v[x]*cnt[x];}
    22 void rotate(int &x,bool a){int y=ch[x][a]; ch[x][a]=ch[y][!a]; ch[y][!a]=x; update(x); update(y); x=y;}
    23 void ins(int &x,ll val){
    24     if(!x){x=++tot; v[x]=sm[x]=val; rnd[x]=rand(); ch[x][0]=ch[x][1]=0; sz[x]=cnt[x]=1; return;}
    25     if(v[x]==val){cnt[x]++; sz[x]++; sm[x]+=val; return;}
    26     if(val<v[x]){ins(ch[x][0],val); update(x); if(rnd[ch[x][0]]<rnd[x])rotate(x,0); return;}
    27     if(val>v[x]){ins(ch[x][1],val); update(x); if(rnd[ch[x][1]]<rnd[x])rotate(x,1); return;}
    28 }
    29 void del(int &x,ll val){
    30     if(v[x]==val){
    31         if(cnt[x]>1){cnt[x]--; sz[x]--; sm[x]-=val; return;}
    32         else{
    33             if(!ch[x][0]||!ch[x][1])x=ch[x][0]+ch[x][1];
    34             else{
    35                 if(rnd[ch[x][0]]<rnd[ch[x][1]])rotate(x,0),del(ch[x][1],val),update(x);
    36                 else rotate(x,1),del(ch[x][0],val),update(x);
    37             }
    38             return;
    39         }
    40     }
    41     if(val<v[x]){del(ch[x][0],val); update(x); return;}
    42     if(val>v[x]){del(ch[x][1],val); update(x); return;}
    43 }
    44 int find(int x,int k){
    45     if(k>sz[ch[x][0]]&&k<=sz[ch[x][0]]+cnt[x])return x;
    46     if(k<=sz[ch[x][0]])return find(ch[x][0],k);
    47     if(k>sz[ch[x][0]]+cnt[x])return find(ch[x][1],k-sz[ch[x][0]]-cnt[x]);
    48 }
    49 ll qs(int x,ll val){
    50     if(val<v[x])return qs(ch[x][0],val);
    51     if(val==v[x])return sm[ch[x][0]];
    52     if(val>v[x])return sm[x]-sm[ch[x][1]]+qs(ch[x][1],val);
    53 }
    54 ll qb(int x,ll val){
    55     if(val>v[x])return qb(ch[x][1],val);
    56     if(val==v[x])return sm[ch[x][1]];
    57     if(val<v[x])return sm[x]-sm[ch[x][0]]+qb(ch[x][0],val);
    58 }
    59 int qss(int x,ll val){
    60     if(val<v[x])return qss(ch[x][0],val);
    61     if(val==v[x])return sz[ch[x][0]];
    62     if(val>v[x])return sz[x]-sz[ch[x][1]]+qss(ch[x][1],val);
    63 }
    64 int qbs(int x,ll val){
    65     if(val>v[x])return qbs(ch[x][1],val);
    66     if(val==v[x])return sz[ch[x][1]];
    67     if(val<v[x])return sz[x]-sz[ch[x][0]]+qbs(ch[x][0],val);
    68 }
    69 int main(){
    70     n=read(); k=read(); inc(i,1,n)a[i]=read(); inc(i,1,k)ins(root,a[i]); int l=1,r=k;
    71     ans=1LL*100000000000;
    72     while(1){
    73         ll x=v[find(root,(k>>1)+1)];
    74         ans=min(ans,x*qss(root,x)-qs(root,x)+qb(root,x)-qbs(root,x)*x);
    75         del(root,a[l]); l++; r++; if(r>n)break; ins(root,a[r]);
    76     }
    77     printf("%lld",ans); return 0;
    78 }

    20160814

  • 相关阅读:
    CSS 导航栏
    CSS 伪元素
    CSS 伪类(Pseudo-classes)
    CSS 组合选择符
    CSS Positioning(定位)
    C# 控制台程序 托盘图标 事件响应
    安装GIT,集成到Powershell中
    Tomcat调优
    CentOS7安装配置redis5集群
    redis.conf配置详细解析
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5778131.html
Copyright © 2011-2022 走看看