• BZOJ1112: [POI2008]砖块Klo(splay)


    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

    解题思路:

    主要是一个规律知道就好了:序列更改为中位数次数最小

    证明吗?

    去问数竞的吧

    好了废话不多说。

    相当于一个长度为k的yy出来的窗口在滑动,splay O(logn)维护中位数即可。

    时间复杂度O(nlogn)

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define lll tr[spc].ch[0]
      5 #define rrr tr[spc].ch[1]
      6 #define ls ch[0]
      7 #define rs ch[1]
      8 #define inp tr[tr[root].ch[1]].ch[0]
      9 using std::min;
     10 using std::abs;
     11 typedef long long lnt;
     12 struct trnt{
     13     int ch[2];
     14     int fa;
     15     int wgt;
     16     int num;
     17     lnt val;
     18     lnt sum;
     19 }tr[1000000],str;
     20 int n,k;
     21 int root;
     22 int top;
     23 int siz;
     24 int grv;
     25 lnt ans;
     26 lnt klo[1000000];
     27 int bin[1000000];
     28 bool whc(int spc)
     29 {
     30     return tr[tr[spc].fa].rs==spc;
     31 }
     32 void pushup(int spc)
     33 {
     34     tr[spc].wgt=tr[lll].wgt+tr[rrr].wgt+tr[spc].num;
     35     tr[spc].sum=tr[spc].val*tr[spc].num+tr[lll].sum+tr[rrr].sum;
     36     return ;
     37 }
     38 void rotate(int spc)
     39 {
     40     int f=tr[spc].fa;
     41     bool k=whc(spc);
     42     tr[f].ch[k]=tr[spc].ch[!k];
     43     tr[spc].ch[!k]=f;
     44     tr[tr[f].fa].ch[whc(f)]=spc;
     45     tr[spc].fa=tr[f].fa;
     46     tr[f].fa=spc;
     47     tr[tr[f].ch[k]].fa=f;
     48     pushup(f);
     49     pushup(spc);
     50     return ;
     51 }
     52 void splay(int spc,int f)
     53 {
     54     while(tr[spc].fa!=f)
     55     {
     56         int ft=tr[spc].fa;
     57         if(tr[ft].fa==f)
     58         {
     59             rotate(spc);
     60             break;
     61         }
     62         if(whc(spc)^whc(ft))
     63             rotate(spc);
     64         else
     65             rotate(ft);
     66         rotate(spc);
     67     }
     68     if(!f)
     69         root=spc;
     70 }
     71 int place(int spc,int rnk)
     72 {
     73     if(tr[lll].wgt>=rnk)
     74         return place(lll,rnk);
     75     if(tr[spc].num+tr[lll].wgt>=rnk)
     76         return spc;
     77     return place(rrr,rnk-tr[spc].num-tr[lll].wgt);
     78 }
     79 int aa;
     80 void maxmin(int spc,int v)
     81 {
     82     if(!spc)
     83         return ;
     84     if(tr[spc].val<v)
     85     {
     86         aa=spc;
     87         return maxmin(rrr,v);
     88     }
     89     return maxmin(lll,v);
     90 }
     91 void minmax(int spc,int v)
     92 {
     93     if(!spc)
     94         return ;
     95     if(tr[spc].val>v)
     96     {
     97         aa=spc;
     98         return minmax(lll,v);
     99     }
    100     return minmax(rrr,v);
    101 }
    102 void del(int &spc)
    103 {
    104     bin[++top]=spc;
    105     tr[spc]=str;
    106     spc=0;
    107     return ;
    108 }
    109 int newp()
    110 {
    111     if(top)
    112         return bin[top--];
    113     return ++siz;
    114 }
    115 void ins(int v)
    116 {
    117     aa=0;
    118     maxmin(root,v);
    119     splay(aa,0);
    120     aa=0;
    121     minmax(root,v);
    122     splay(aa,root);
    123     if(inp)
    124     {
    125         tr[inp].num++;
    126         tr[inp].wgt++;
    127     }else{
    128         inp=newp();
    129         tr[inp].fa=tr[root].rs;
    130         tr[inp].num=tr[inp].wgt=1;
    131         tr[inp].val=v;
    132     }
    133     pushup(inp);
    134     pushup(tr[root].rs);
    135     pushup(root);
    136     return ;
    137 }
    138 void Del(int v)
    139 {
    140     aa=0;
    141     maxmin(root,v);
    142     splay(aa,0);
    143     aa=0;
    144     minmax(root,v);
    145     splay(aa,root);
    146     tr[inp].num--;
    147     if(!tr[inp].num)
    148         del(inp);
    149     else
    150         pushup(inp);
    151     pushup(tr[root].rs);
    152     pushup(root);
    153     return ;
    154 }
    155 void update()
    156 {
    157     splay(1,0);
    158     splay(2,1);
    159     int x=place(inp,grv);
    160     splay(x,2);
    161     int spc=inp;
    162     ans=min(ans,abs(tr[lll].sum-tr[lll].wgt*tr[inp].val)+abs(tr[rrr].sum-tr[rrr].wgt*tr[inp].val));
    163     return ;
    164 }
    165 int main()
    166 {
    167     root=1;
    168     siz=2;
    169     tr[root].val=-100;
    170     tr[root].rs=2;
    171     tr[2].val=0x3f3f3f3f3f3f3f3fll;
    172     tr[2].fa=1;
    173     scanf("%d%d",&n,&k);
    174     grv=(k+1)>>1;
    175     for(int i=1;i<=n;i++)
    176         scanf("%lld",&klo[i]);
    177     for(int i=1;i<=k;i++)
    178         ins(klo[i]);
    179     ans=0x7f7f7f7f7f7f7f7fll;
    180     update();
    181     for(int i=k+1;i<=n;i++)
    182     {
    183         Del(klo[i-k]);
    184         ins(klo[i]);
    185         update();
    186     }
    187     printf("%lld
    ",ans);
    188     return 0;
    189 }
    190 
  • 相关阅读:
    移动硬盘文件被恶意隐藏
    asp.net identity UserSecurityStamp 的作用
    Head First Python学习笔记1
    WPF 确认动态加载数据完成
    rust by example 2
    Rust by Example1
    奇葩!把类型转成object
    Lambda高手之路第一部分
    理解Lambda表达式
    贪心算法-找零钱(C#实现)
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/9672304.html
Copyright © 2020-2023  润新知