一道很有意思的神题~

暴力平衡树的复杂度很对(并不),但是$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. dfs___刷题记录

    poj 1564 给出一个s,n个数,输出所有的能够得到s的方案 #include<cstdio> #include<cstring> #include<iostream ...

  2. css——外部样式

    外部样式 先建立一个css文件,如下: 然后开始写代码,不要加<style> 然后可以在html文件中的<head>内引用:<link rel="stylesh ...

  3. gcp – 源于CP的高级命令行文件拷贝工具

    作者:linux 出处:http://linux.cn/thread/11868/1/1/ gcp – 源于CP的高级命令行文件拷贝工具 几周前,我们讨论了高级拷贝(修改于cp命令,让其可以显示复制进 ...

  4. [php]如何做到高并发优化

    在实际的开发过程中我们遇到过各种各样的活动,但像用户流量较大的平台就需要考虑高并发的问题,但是如何去解决呢?我总结了几种解决方案,欢迎大家指正! 一.什么是PV/UV/QPS? PV:页面访问量,即P ...

  5. VUE:事件处理和表单输入绑定

    事件处理 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <titl ...

  6. Ubuntu下使用crontab部署定时任务

    Ubuntu下使用crontab部署定时任务 安装cron apt-get install cron 开启crontab日志 默认情况下的日志是没有开启的,我们需要找到 /etc/rsyslog.d/ ...

  7. Ajax得到JSON数据

    Ajax得到JSON数据

  8. 将Oracle中的数据放入elasticsearch

    package com.c4c.test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Res ...

  9. java中new一个对象的执行过程及类的加载顺序

    1,new一个对象时代码的执行顺序 (1)加载父类(以下序号相同,表明初始化是按代码从上到下的顺序来的) 1.为父类的静态属性分配空间并赋于初值 1.执行父类静态初始化块; (2)加载子类 2.为子类 ...

  10. EOSS V3.0.2 企业运营支撑系统(基于RBAC原理的权限管理)

    下载地址:https://github.com/jelly-liu/EOSS 一:EOSS 功能介绍 其于用户,角色,权限,资源(即菜单)的一套"简约有用"的权限管理系统,可在其基 ...