一道很有意思的神题~

暴力平衡树的复杂度很对(并不),但是$2^{30}$的空间一脸屎

这题的正解是一个类似线段树的数据结构,我觉得很有创新性Orz

首先可以想到一种暴力就是用一个点代表一个区间,然后用链表维护这些点的集合,每次alloc操作就相当于割开未分配的区间,即增加了一个点,free操作就相当于合并。所以最多会产生$n$个点,单次操作$O(n)$,时间复杂度$O(n^2)$但是不满,貌似常数小就可以拿60;

把这个集合看成一个序列的话,快速修改点的信息肯定会想到线段树,正解就是用线段树去维护这个“区间集合”;

但是直接暴力线段树的话并不比平衡树优,需要用类似区间修改打懒标记的方法:如果一个点没被分割过,那就先打上标记,不实际创建它的儿子,到访问时才真正建出来,这样就能达到每次操作均摊$O(logn)$的复杂度。

开始算了算$2^{30}$线段树需要一千多万个节点,觉得很虚,结果一看空间1G瞬间不虚。。。

其实我一直很喜欢这种二叉结构,觉得很优美,写起来也很舒服。。。

代码:

 #include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define inf 2147483647
#define eps 1e-9
#define DCSB {puts("failed");continue;}
using namespace std;
typedef long long ll;
struct node{
int lc,rc,v,bit;
}t[];
int T,n,op,p,q,rt,cnt,tot,rts[];
void pd(int u){
if(t[u].bit==-)return;
if(t[u].bit>){
t[u].lc=++cnt;
t[u].rc=++cnt;
t[t[u].lc].bit=t[t[u].rc].bit=t[u].bit-;
t[t[u].lc].v=t[t[u].rc].v=<<(t[u].bit-);
}else t[u].lc=t[u].rc=-;
t[u].bit=-;
}
int ins(int u,int p){
int now=++cnt,ret=now;
pd(u);
while(t[u].lc!=-){
t[now].bit=-;
t[u].v-=p;
t[now].v=p;
if(p<t[t[u].lc].v){
t[now].rc=;
now=t[now].lc=++cnt;
u=t[u].lc;
}else{
p-=t[t[u].lc].v;
t[now].lc=t[u].lc;
t[now].rc=++cnt;
t[u].lc=;
now=t[now].rc;
u=t[u].rc;
}
pd(u);
}
t[u].v-=p;
t[now].bit=-;
t[now].v=p;
t[now].lc=-;
return ret;
}
int del(int u,int v){
if(!u||!v)return u|v;
if(t[u].lc!=-){
t[u].lc=del(t[u].lc,t[v].lc);
t[u].rc=del(t[u].rc,t[v].rc);
}
t[u].v+=t[v].v;
return u;
}
int calc(int u,int p){
int ret=;
while(t[u].bit==-&&t[u].lc!=-){
ret*=;
if(t[u].lc&&p<t[t[u].lc].v)u=t[u].lc;
else{
p-=t[t[u].lc].v;
u=t[u].rc;
ret++;
}
}
if(t[u].bit==-)return ret;
else return ret*(<<t[u].bit)+p;
}
int main(){
scanf("%d",&T);
while(T--){
rt=cnt=;
t[].bit=;
t[].v=<<;
tot=;
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d",&op);
if(op==){
scanf("%d",&p);
rts[++tot]=;
if(t[rt].v<p)DCSB
rts[tot]=ins(rt,p);
puts("ok");
}
if(op==){
scanf("%d",&p);
if(p>tot||!rts[p])DCSB
rt=del(rt,rts[p]);
rts[p]=;
puts("ok");
}
if(op==){
scanf("%d%d",&p,&q);
if(p>tot||!rts[p]||q>=t[rts[p]].v)DCSB
printf("%d\n",calc(rts[p],q));
}
}
}
return ;
}

(2016北京集训十)【xsy1530】小Q与内存的更多相关文章

  1. (2016北京集训十)【xsy1528】azelso - 概率期望dp

    北京集训的题都是好题啊~~(于是我爆0了) 注意到一个重要的性质就是期望是线性的,也就是说每一段的期望步数可以直接加起来,那么dp求出每一段的期望就行了... 设$f_i$表示从$i$出发不回到$i$ ...

  2. (2016北京集训十)【xsy1529】小Q与进位制 - 分治FFT

    题意很简单,就是求这个数... 其实场上我想出了分治fft的正解...然而不会打...然后打了个暴力fft挂了... 没啥好讲的,这题很恶心,卡常卡精度还爆int,要各种优化,有些dalao写的很复杂 ...

  3. (2016北京集训十四)【xsy1556】股神小D - LCT

    题解: 题解居然是LCT……受教了 把所有区间按照端点排序,动态维护目前有重叠的区间,用LCT维护即可. 代码: #include<algorithm> #include<iostr ...

  4. (2016北京集训十四)【xsy1557】task

    题解: 限制可以看成图状结构,每个任务的对物品数量的影响可以看成权值,只不过这个权值用一个五元组来表示. 那么题意要求的就是最大权闭合子图,网络流经典应用. 代码: #include<algor ...

  5. (2016北京集训十二)【xsy1542】疯狂求导

    题解: 这题看起来很难...但是实际上并没有想象中的那么难 第一眼看上去不会求导公式怎么办?不要紧,题目背景非常良心的给出了题目中的导数计算公式 求完导合并同类项很恶心怎么办?不要紧,样例解释说明了不 ...

  6. [2016北京集训测试赛5]小Q与内存-[线段树的神秘操作]

    Description Solution 哇真的异常服气..线段树都可以搞合并和拆分的啊orzorz.神的世界我不懂 Code #include<iostream> #include< ...

  7. 2016北京集训 小Q与进位制

    题目大意 一个数每一位进制不同,已知每一位的进制,求该数的十进制表达. 显然有 $$Ans=\sum\limits_{i=0}^{n-1}a_i \prod\limits_{j=0}^{i-1}bas ...

  8. 2016北京集训测试赛(十四)Problem B: 股神小D

    Solution 正解是一个\(\log\)的link-cut tree. 将一条边拆成两个事件, 按照事件排序, link-cut tree维护联通块大小即可. link-cut tree维护子树大 ...

  9. 2016北京集训测试赛(十四)Problem A: 股神小L

    Solution 考虑怎么卖最赚钱: 肯定是只卖不买啊(笑) 虽然说上面的想法很扯淡, 但它确实能给我们提供一种思路, 我们能不买就不买; 要买的时候就买最便宜的. 我们用一个优先队列来维护股票的价格 ...

随机推荐

  1. ZBrush模型的细分

    在ZBrush®中对模型进行雕刻时,随着细节越来越丰富,原有的面数已经不能满足我们对细节的要求,为了得到更多的细节,我们就必须增加模型的面数,让更多的面来支持我们进行雕刻,如下图(左)和下图(右)所示 ...

  2. Java基础——Servlet

    什么是Servlet Servlet是Java Web的三大组件之一,它属于动态资源.Servlet的作用是处理请求,服务器会把接收到的请求交给Servlet来处理,在Servlet中通常需要: l  ...

  3. 七、利用frp 穿透到内网的http/https网站,实现对外开放

    有域名的话使用域名,没有域名的话使用IP注意80端口是否被已经安装使用的nginx占用,若被占用,可以换成其他端口,比如8080,,或者利用nginx的反向代理实现frp服务端与nginx共用80端口 ...

  4. centos7最小化安装Oracle11gR2

    1.准备CentOS 7 系统环境 我以 CentOS-7-x86_64-DVD-1511.iso 为例,简述Oracle 11g的安装过程. 由于是使用静默模式(silent)安装的,无需使用图形化 ...

  5. MySQL 面试题(一)

    原文地址:http://www.2cto.com/database/201311/254385.html 作者:黄杉(红黑联盟) 公司招聘MySQL DBA面试心得 1    2年MySQL DBA经 ...

  6. LAMP自动安装脚本

    #!/bin/bash # 功能描述:LAMP自动安装脚本 # 初始化 if [ "$(cat /etc/system-release | awk '{print $(NF-1)}' | a ...

  7. 小学生都能学会的python(列表[ ])

    小学生都能学会的python(列表[ ]) 1. 什么是列表(list) 能装东西的东西 列表中装的数据是没有限制的, 大小基本上是够用的 列表使用[]来表示. 在列表中每个元素与元素之间用逗号隔开 ...

  8. 小学生都能学会的python(编码 and 字符串)

    小学生都能学会的python(编码 and 字符串) 一,编码 最早的计算机编码是ASCII. 有英文+数字+特殊字符 8bit => 1byte 没有中文, 后面的编码必须兼容ASCII    ...

  9. MyEclipse 设置JSP,HTML的默认打开方式,避免出现打开后上面出现浏览器

    1. 2. 3. jsp的设置一样,这样myeclipse打开jsp就不会出现上面的浏览器了

  10. tomcat闪退无法启动 the catalina_home environment variable is not defined correctly this environment variable is needed to run this program

    未成功配置CATALINA_HOME 1.计算机>属性>环境变量, 新建环境变量.变量名为CATALINA_HOME ,变量值tomcat的解压目录,注意后面不用多加“\”或者“;” 2. ...