(2016北京集训十)【xsy1530】小Q与内存

一道很有意思的神题~
暴力平衡树的复杂度很对(并不),但是$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与内存的更多相关文章
- (2016北京集训十)【xsy1528】azelso - 概率期望dp
北京集训的题都是好题啊~~(于是我爆0了) 注意到一个重要的性质就是期望是线性的,也就是说每一段的期望步数可以直接加起来,那么dp求出每一段的期望就行了... 设$f_i$表示从$i$出发不回到$i$ ...
- (2016北京集训十)【xsy1529】小Q与进位制 - 分治FFT
题意很简单,就是求这个数... 其实场上我想出了分治fft的正解...然而不会打...然后打了个暴力fft挂了... 没啥好讲的,这题很恶心,卡常卡精度还爆int,要各种优化,有些dalao写的很复杂 ...
- (2016北京集训十四)【xsy1556】股神小D - LCT
题解: 题解居然是LCT……受教了 把所有区间按照端点排序,动态维护目前有重叠的区间,用LCT维护即可. 代码: #include<algorithm> #include<iostr ...
- (2016北京集训十四)【xsy1557】task
题解: 限制可以看成图状结构,每个任务的对物品数量的影响可以看成权值,只不过这个权值用一个五元组来表示. 那么题意要求的就是最大权闭合子图,网络流经典应用. 代码: #include<algor ...
- (2016北京集训十二)【xsy1542】疯狂求导
题解: 这题看起来很难...但是实际上并没有想象中的那么难 第一眼看上去不会求导公式怎么办?不要紧,题目背景非常良心的给出了题目中的导数计算公式 求完导合并同类项很恶心怎么办?不要紧,样例解释说明了不 ...
- [2016北京集训测试赛5]小Q与内存-[线段树的神秘操作]
Description Solution 哇真的异常服气..线段树都可以搞合并和拆分的啊orzorz.神的世界我不懂 Code #include<iostream> #include< ...
- 2016北京集训 小Q与进位制
题目大意 一个数每一位进制不同,已知每一位的进制,求该数的十进制表达. 显然有 $$Ans=\sum\limits_{i=0}^{n-1}a_i \prod\limits_{j=0}^{i-1}bas ...
- 2016北京集训测试赛(十四)Problem B: 股神小D
Solution 正解是一个\(\log\)的link-cut tree. 将一条边拆成两个事件, 按照事件排序, link-cut tree维护联通块大小即可. link-cut tree维护子树大 ...
- 2016北京集训测试赛(十四)Problem A: 股神小L
Solution 考虑怎么卖最赚钱: 肯定是只卖不买啊(笑) 虽然说上面的想法很扯淡, 但它确实能给我们提供一种思路, 我们能不买就不买; 要买的时候就买最便宜的. 我们用一个优先队列来维护股票的价格 ...
随机推荐
- PHP小常识分享
PHP 标记 当解析一个文件时,PHP 会寻找起始和结束标记,也就是 <?php 和 ?>,这告诉 PHP 开始和停止解析二者之间的代码.此种解析方式使得 PHP 可以被嵌入到各种不同的文 ...
- Python 进行网络编程
Date: 2019-06-10 Author: Sun 1. Python TCP通信实现 socket()函数 Python 中,我们用 socket()函数来创建套接字,语法格式如下: sock ...
- getattibute 与 getparameter区别
1.getAttribute是取得jsp中 用setAttribute设定的attribute 2.parameter得到的是string:attribute得到的是object 3.request ...
- input的radio根据value和name反向显示
1.获取radio的值,是根据name设置一组单选框. 例如: <div id="sexBox"> <input type="radio" i ...
- easyUI combobox的使用
1.需要用到的方法 设置组合框(combobox)值的数组. $('#cc').combobox('setValues', ['001','002']); 设置组合框(combobox)的值. $(' ...
- 设置Django关闭Debug后的静态文件路由
Django在Debug模式关闭掉后请求静态文件时,返回404相应码,后台的请求url是"GET /static/css/404.css HTTP/1.1" 404 1217,找不 ...
- Windows 错误 0x80070570
Windows程序运行或者删除文件提示错误0x80070570:文件或目录损坏且无法读取. 环境 Windows 10 解决办法 管理员权限打开cmd,输入chkdsk 盘符: /f,提示输入Y,修复 ...
- php 与 nginx 的两种处理方式
1.IP:Port 监听方式 php-fpm docker pull PHP:2.4-alpine nginx.conf fastcgi_pass 127.0.0.1:9000; php-fpm 在容 ...
- 移动端优先的flex三栏布局
默认情况下先显示移动端,通过 @media 属性适配屏幕变化 使用flexbox相关的CSS属性 display: flex; (父元素) flex-wrap: nowrap | wrap | wra ...
- 小学生绞尽脑汁也学不会的python(反射)
小学生绞尽脑汁也学不会的python(反射) 1. issubclass, type, isinstance issubclass 判断xxxx类是否是xxxx类的子类 type 给出xxx的数据类型 ...