【POI2008】【BZOJ1112】砖块Klo

来源:互联网 发布:SQL是面向问题的语言吗 编辑:程序博客网 时间:2024/03/29 01:21

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
HINT

原题还要求输出结束状态时,每柱砖的高度.本题略去.

Source

平衡树维护一下找中位数

太久不写权值平衡树现在又已经快忘光了QAQ

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define GET (ch>='0'&&ch<='9')#define MAXN 100010#define LL long long#define MAXLL 1ll<<60#define MAXINT 0x3f3f3f3fusing namespace std;int n,k,cnt,root;int h[MAXN];LL ans=MAXLL;struct splay{    int ch[2],fa,size,val;    LL sum;}tree[MAXN];void push_up(int x){    if (!x) return;    tree[x].size=tree[tree[x].ch[0]].size+tree[tree[x].ch[1]].size+1;    tree[x].sum=tree[tree[x].ch[0]].sum+tree[tree[x].ch[1]].sum+tree[x].val;}void rot(int x,int &f){    int y=tree[x].fa,z=tree[y].fa,l,r;    l=(tree[y].ch[1]==x);r=l^1;    if (y==f)   f=x;    else    tree[z].ch[tree[z].ch[1]==y]=x;    tree[tree[x].ch[r]].fa=y;tree[y].fa=x;tree[x].fa=z;    tree[y].ch[l]=tree[x].ch[r];tree[x].ch[r]=y;    push_up(y);push_up(x);}void Splay(int x,int &f){    while (x!=f)    {        int y=tree[x].fa,z=tree[y].fa;        if (y!=f)        {            if ((tree[y].ch[0]==x)^(tree[z].ch[0]==y))  rot(x,f);            else     rot(y,f);        }        rot(x,f);    }}void insert(int val){    int i;    for (i=root;tree[i].ch[val>tree[i].val];i=tree[i].ch[val>tree[i].val]);    tree[i].ch[val>tree[i].val]=++cnt;tree[cnt].fa=i;    tree[cnt].val=tree[cnt].sum=val;tree[cnt].size=1;    Splay(cnt,root);}int find(int x,int k){    int l=tree[x].ch[0],r=tree[x].ch[1];    if (tree[l].size+1==k)  return x;    if (tree[l].size>=k)    return find(l,k);    return find(r,k-tree[l].size-1);}void del(int val){    int i,j;    for (i=root;tree[i].val!=val;i=tree[i].ch[val>tree[i].val]);    Splay(i,root);    if (!tree[root].ch[1])  {root=tree[root].ch[0];return;}    for (j=tree[root].ch[1];tree[j].ch[0];j=tree[j].ch[0]);    Splay(j,tree[root].ch[1]);    tree[j].ch[0]=tree[root].ch[0];tree[tree[root].ch[0]].fa=j;    tree[j].fa=0;root=j;push_up(j);}void in(int &x){    char ch=getchar();x=0;    while (!GET)    ch=getchar();    while (GET) x=x*10+ch-'0',ch=getchar();}int main(){    in(n);in(k);    for (int i=1;i<=n;i++)    {        in(h[i]);insert(h[i]);        if (i>k)    del(h[i-k]);        if (i>=k)        {            int x=find(root,(k+1)>>1);Splay(x,root);            int l=tree[x].ch[0],r=tree[x].ch[1];            ans=min(ans,tree[r].sum+(LL)tree[x].val*(tree[l].size-1)-tree[l].sum-(LL)tree[x].val*(tree[r].size-1));        }    }    cout<<ans<<endl;}
1 0
原创粉丝点击