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

转载于:https://www.cnblogs.com/YuanZiming/p/5778131.html

bzoj1112[POI2008]砖块Klo*相关推荐

  1. BZOJ1112 - [POI2008]砖块Klo

    原题链接 题意简述 给出一个n(n≤105)n(n \leq 10^5)个数的序列a(max{a}≤106)a(max\{a\}\leq10^6),每次给一个数+1/-1.求使得序列中存在连续k(k≤ ...

  2. BZOJ1112[POI2008]砖块Klo——非旋转treap

    题目描述 N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次数的动作完成任 ...

  3. 【主席树】bzoj1112: [POI2008]砖块Klo

    数据结构划一下水 Description N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. ...

  4. BZOJ1112: [POI2008]砖块Klo(洛谷P3466)

    平衡树 BZOJ题目传送门 洛谷题目传送门 动态维护中位数,平衡树上一发就好了. 代码: #include<cctype> #include<cstdio> #include& ...

  5. BZOJ1112: [POI2008]砖块Klo

    Description N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次 ...

  6. bzoj1112: [POI2008]砖块Klo(splay)

    题面在这里 做法 枚举每长度为 k k k 的段寻找中位数即可.splay维护. 代码 => 主要是想说这一点,由于计算的必要,相同的数不能合并到一个节点,否则之后调用 sum[ch[x][0] ...

  7. 1112: [POI2008]砖块Klo

    1112: [POI2008]砖块Klo Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 1245  Solved: 426 [Submit][Sta ...

  8. [POI2008]砖块Klo

    1112: [POI2008]砖块Klo Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2910 Solved: 1026 [Submit][Stat ...

  9. [POI2008] 砖块Klo

    洛谷 P3466 传送门 bzoj 1112 传送门 用treap维护一段长为k的区间即可. 先把1~k-1的都插入treap. 然后从k到n进行如下操作: 插入一个,计算,删除一个. 用到一个结论: ...

最新文章

  1. 【推荐系统】基于知识图谱的推荐系统总结
  2. pagefile.sys
  3. UITextView自定义placeholder功能:用一个label写了文字,然后当检测到长度不为0的时候就把label隐藏...
  4. 新增了归并数组的方法!
  5. Hbase API学习
  6. 阅读-《金字塔原理》
  7. smart原则_设立目标的smart原则
  8. RRR-RR五边形平面并联机构分析:Kinematics of a five-bar RRR-RR mechanism
  9. linspace函数
  10. 老路《用得上的商学课》学习开篇(自序)
  11. 中国文学通史之各个阶段介绍
  12. ubuntu安装以太方mist
  13. 没有项目种类分配到科目 1901090000/KTK
  14. 移动端开发使用rem时动态设置html的字体大小
  15. wincc服务器不可用项目打不开,wincc客户端与服务器同步
  16. kso经验积累 -- c#发送邮件
  17. idea java 语法高亮_Intellij IDEA 中JAVA常用配置项总结
  18. Vue-路由传参的方法与区别
  19. 股票预测 - ARIMA
  20. 电子技术与计算机软件杂志,《电子技术与软件工程》杂志社

热门文章

  1. 〖Python 数据库开发实战 - MongoDB篇⑧〗- MongoDB的数据结构
  2. 【工具篇】Unity自定义取色板颜色获取
  3. 5.27模拟题 逃避系统警察
  4. css 特效 火球 光,JS+CSS实现炫酷光感效果
  5. 最快速的编程学习方法究竟是什么?
  6. Postman 调试请求Asp.NetCore3.1WebApi Get/Post/Put/Delete文件上传等
  7. Micropython 家庭智能系统工程化设计
  8. java获取图片的分辨率_Java读取图片分辨率
  9. iptv工作原理详解
  10. 动车组在京沪高铁打破铁路最高运营速度纪录