• BZOJ1112: [POI2008]砖块Klo


    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1112
    题目大意:N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次数的动          作完成任务.
    题解:我们看看n是106于是我们可以枚举k,是O(n)的,那么看看时间复杂度,就需要一个logN的算法来删除一个数,加入一个数,寻找第k个数,于是平衡树即可!时间复杂度:NlogN;
       实际上刚开始想的是二分次数+二分长度,想想应该也是可行的,只不过在答案验证上,可以自己想想,反正我不知道!
      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<algorithm>
      5 #include<cmath>
      6 #define maxn 100005
      7 #define ll long long 
      8 #define linf 9223372036854775807LL
      9 using namespace std;
     10 int n,k,root,mid,mmid,sz;
     11 ll tmp;
     12 ll sum1,sum2,ans;
     13 int a[maxn];
     14 int ls[maxn],rs[maxn],size[maxn],w[maxn],rnd[maxn];
     15 ll sum[maxn],v[maxn];
     16 int read()
     17 {
     18     int x=0; char ch; bool bo=0;
     19     while (ch=getchar(),ch<'0'||ch>'9') if (ch=='-') bo=1;
     20     while (x=x*10+ch-'0',ch=getchar(),ch>='0'&&ch<='9');
     21     if (bo) return -x; return x;
     22 }
     23 void updata(int k)
     24 {
     25     sum[k]=sum[ls[k]]+sum[rs[k]]+w[k]*v[k];
     26     size[k]=size[ls[k]]+size[rs[k]]+w[k];
     27 }
     28 void rturn(int &k)
     29 {
     30     int t=ls[k]; ls[k]=rs[t]; rs[t]=k; updata(k); updata(t); k=t; return;
     31 }
     32 void lturn(int &k)
     33 {
     34     int t=rs[k]; rs[k]=ls[t]; ls[t]=k; updata(k); updata(t); k=t; return;
     35 }
     36 void ins(int &k,int val)
     37 {
     38     if (!k) 
     39     {
     40         k=++sz; size[k]=w[k]=1; v[k]=sum[k]=val; rnd[k]=rand(); return ;
     41     }
     42     size[k]++; sum[k]+=val;
     43     if (val==v[k]) w[k]++;
     44     if (v[k]>val){ins(ls[k],val); if (rnd[ls[k]]>rnd[k]) rturn(k);}
     45     if (v[k]<val){ins(rs[k],val); if (rnd[rs[k]]>rnd[k]) lturn(k);}
     46     updata(k);
     47 }
     48 void del(int &k,int val)
     49 {
     50     if (!k) return ;
     51     if (v[k]==val)
     52     {
     53         if (w[k])
     54         {
     55             w[k]--; size[k]--; sum[k]-=val; return ;
     56         }
     57         if (ls[k]*rs[k]==0) k=ls[k]+rs[k];
     58         else
     59         {
     60             if (rnd[ls[k]]>rnd[rs[k]]) {rturn(k); del(k,val);}
     61             else {lturn(k); del(k,val);}
     62         }
     63     }
     64     else if (v[k]>val) {sum[k]-=val; size[k]--; del(ls[k],val);}
     65     else {sum[k]-=val; size[k]--; del(rs[k],val);}
     66 }
     67 void init()
     68 {
     69     n=read(); k=read(); mmid=k/2+1; ans=linf;
     70     for(int i=1; i<=n; i++) a[i]=read();
     71 }
     72 void find(int k,int rank)
     73 {
     74     if(!k)return;    
     75     if(rank>size[ls[k]]&&rank<=size[ls[k]]+w[k])
     76     {
     77         sum1+=(sum[ls[k]]+(rank-size[ls[k]]-1)*v[k]);
     78         sum2+=(sum[rs[k]]+(size[ls[k]]+w[k]-rank)*v[k]);
     79         tmp=v[k];
     80     }
     81     else if(rank<=size[ls[k]])
     82     {
     83         sum2+=(v[k]*w[k]+sum[rs[k]]);
     84         find(ls[k],rank);
     85     }
     86     else 
     87     {
     88         sum1+=(v[k]*w[k]+sum[ls[k]]);
     89         find(rs[k],rank-size[ls[k]]-w[k]);
     90     }
     91 }  
     92 void getans()
     93 {
     94     sum1=sum2=0;
     95     find(root,mmid);
     96     ll sum=(mmid-1)*tmp-sum1+sum2-(k-mmid)*tmp;
     97     if(sum<ans)ans=sum;
     98 }
     99 void solve()
    100 {
    101     root=0;
    102     for (int i=1; i<=k; i++) ins(root,a[i]); 
    103     getans();
    104     for (int i=k+1; i<=n; i++)
    105     {
    106         del(root,a[i-k]); ins(root,a[i]);
    107         getans();
    108     }
    109     printf("%lld
    ",ans);
    110 }
    111 int main()
    112 {
    113     init();
    114     solve();
    115 } 
    View Code
  • 相关阅读:
    MyEclipse取消自动跳到Console窗口
    JAVA Socket超时浅析
    利用WireShark进行DNS协议分析
    SSL/TLS协议工作流程
    Linux下安装MySQL
    使用Java中的动态代理实现数据库连接池
    在Linux下安装和使用MySQL
    自省 另外一种python 生成随机在base36 之间的兑换码生成。
    python 时间转换相关
    关于utf8mb4的学习了解笔记
  • 原文地址:https://www.cnblogs.com/HQHQ/p/5630045.html
Copyright © 2020-2023  润新知