• bzoj 1112 [POI2008]砖块Klo


     [POI2008]砖块Klo

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2196  Solved: 787
    [Submit][Status][Discuss]

    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

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

     
    题解:水水的一道题目,划水就可以过了。
       因为区间k固定,所以每次绝对是取中位数的,
       那么只需要一个数据结构,支持寻找中位数,插入,删除,
       求和,这些即可。
       
       那就是Treap瞎搞即可。
      1 #include<cstring>
      2 #include<cmath>
      3 #include<iostream>
      4 #include<algorithm>
      5 #include<cstdio>
      6 
      7 #define ll long long
      8 #define ls tr[p].l
      9 #define rs tr[p].r
     10 #define N 100007
     11 using namespace std;
     12 const ll inf=2000000000000010;
     13 inline ll read()
     14 {
     15     ll x=0,f=1;char ch=getchar();
     16     while(ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();}
     17     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
     18     return x*f;
     19 }
     20 
     21 ll n,sz,rt,ans,k;
     22 ll a[N];
     23 struct Node
     24 {
     25     ll l,r,val,siz,rnd,ct,sum;//记录左儿子,右儿子,点值,该子树大小,随机的值,该点值出现的次数。 
     26 }tr[N*10];//最多多少个节点,就开多少空间 
     27 
     28 inline int rand()
     29 {
     30     static ll seed = 2333;
     31     return seed = (ll)((((seed ^ 998244353) + 19260817ll) * 19890604ll) % 1000000007);
     32 }
     33 inline void update(ll p)
     34 {
     35     tr[p].siz=tr[ls].siz+tr[rs].siz+tr[p].ct;
     36     tr[p].sum=tr[ls].sum+tr[rs].sum+tr[p].ct*tr[p].val;
     37 }
     38 void lturn(ll &p)
     39 {
     40     ll t=tr[p].r;tr[p].r=tr[t].l;tr[t].l=p;
     41     update(t),update(p);p=t;
     42 }
     43 void rturn(ll &p)
     44 {
     45     ll t=tr[p].l;tr[p].l=tr[t].r;tr[t].r=p;
     46     tr[t].siz=tr[p].siz;update(p);p=t;
     47 }
     48 void ins(ll &p,ll x)
     49 {
     50     if (p==0)
     51     {
     52         p=++sz;
     53         tr[p].siz=tr[p].ct=1,tr[p].val=x,tr[p].sum=x,tr[p].rnd=rand();
     54         return;
     55     }
     56     tr[p].siz++;
     57     if (tr[p].val==x) tr[p].ct++;
     58     else if (x>tr[p].val)
     59     {
     60         ins(tr[p].r,x);
     61         if (tr[rs].rnd<tr[p].rnd) lturn(p);
     62     }else
     63     {
     64         ins(tr[p].l,x);
     65         if (tr[ls].rnd<tr[p].rnd) rturn(p);
     66     }
     67     update(p);
     68 }
     69 void del(ll &p,ll x)
     70 {
     71     if (p==0) return;
     72     if (tr[p].val==x)
     73     {
     74         if (tr[p].ct>1) tr[p].ct--,tr[p].siz--,tr[p].sum-=x;//如果有多个直接减一即可。
     75         else
     76         {
     77             if (ls==0||rs==0) p=ls+rs;//单节点或者空的话直接儿子移上来或者删去即可。
     78             else if (tr[ls].rnd<tr[rs].rnd) rturn(p),del(p,x);
     79             else lturn(p),del(p,x); 
     80         }
     81     }
     82     else if (x>tr[p].val) tr[p].siz--,del(rs,x),tr[p].sum-=x;
     83     else tr[p].siz--,del(ls,x),tr[p].sum-=x;
     84     update(p);
     85 }
     86 void solve(ll p,ll x,ll &sum,ll &num,ll &ge,ll &zhi)
     87 {
     88     if (tr[ls].siz>=x) solve(ls,x,sum,num,ge,zhi);
     89     else
     90     {
     91         x-=tr[ls].siz,sum+=tr[ls].sum,num+=tr[ls].siz;
     92         if (tr[p].ct>=x)
     93         {
     94             ge=tr[p].ct;
     95             zhi=tr[p].val;
     96             return;
     97         }
     98         x-=tr[p].ct,sum+=tr[p].val*tr[p].ct,num+=tr[p].ct;
     99         solve(rs,x,sum,num,ge,zhi);
    100     }
    101 }
    102 int main()
    103 {
    104     freopen("fzy.in","r",stdin);
    105     freopen("fzy.out","w",stdout);
    106     
    107     n=read(),k=read();
    108     for (ll i=1;i<=k;i++)
    109         a[i]=read(),ins(rt,a[i]);
    110 //    cout<<tr[rt].val<<endl;    
    111     ans=inf;
    112     for (ll i=k+1;i<=n+1;i++)
    113     {
    114         ll x=0,y=0,z=0,d=0;
    115         solve(rt,(k+1)/2,x,y,z,d);
    116         //cout<<x<<" "<<y<<" "<<z<<" "<<d<<endl;
    117         ll res=0;
    118         res+=d*y-x;
    119         res+=tr[rt].sum-x-z*d-d*(tr[rt].siz-y-z);
    120         ans=min(ans,res);
    121         if (i<=n)
    122         {
    123             del(rt,a[i-k]);
    124             a[i]=read();
    125             ins(rt,a[i]);
    126         }
    127     }
    128     printf("%lld",ans);
    129 }
  • 相关阅读:
    SharePoint自动化系列——Add content type to list.
    Java中通过Selenium WebDriver定位iframe中的元素
    Mac环境下用Java(Sikuli+Robot)实现页游自动化
    PowerShell处理RSS信息
    用Python脚本做一些网页游戏中力所能及的自动化任务
    利用Spire for .NET实现办公自动化——Spire.Doc
    两道关于数据处理方面的面试题
    用C#钩子写一个改键外挂
    C#实现中国天气网JSON接口测试
    C#实现中国天气网XML接口测试
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8065771.html
Copyright © 2020-2023  润新知