博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【题解】BZOJ 3065: 带插入区间K小值——替罪羊树套线段树
阅读量:4638 次
发布时间:2019-06-09

本文共 2939 字,大约阅读时间需要 9 分钟。

题解

orz vfk的题解

3065: 带插入区间K小值 系列题解

1118541-20170426162334272-2026327333.png

一开始用了一种空间常数很大的方法,每次重构的时候merge两颗线段树,然后无限RE(其实是MLE)。

后来改成枚举子树元素插入,空间缩小为约 \(\frac 1 4\) ,然而TLE。

然后把替罪羊树的 \(\alpha\) 从 0.6改成0.75,就卡过了。

OI很休闲的

OI很休闲的

OI很休闲的

OI很休闲的

OI很休闲的

代码

#include 
using namespace std;const int MAXN=140005, MAXM=3e7, MAXB=2e7, MX=70000;const double al=0.75;char BUF[MAXB], *cp=BUF;void rd(int &x){ x=0; while(*cp<'0'||'9'<*cp)cp++; while('0'<=*cp&&*cp<='9')x=x*10+*cp++-'0';}char rc(){while(*cp<'A'||'Z'<*cp)cp++; return *cp++;}int N, M, L, R, TOP, top, ov;int nt, tot, ok, A[MAXN];struct Seg{ Seg *lc, *rc; int s; void *operator new(size_t); void operator delete(void *); Seg(); void up(){s=lc->s+rc->s;}}tr[MAXM], *ST[MAXM], *tmp[MAXN];void *Seg::operator new(size_t size){return ST[--TOP];}void Seg::operator delete(void *p){ST[TOP++]=(Seg*)p;}Seg::Seg(){lc=rc=tr;s=0;}void dec(Seg *&x){ if(x==tr) return; dec(x->lc); dec(x->rc); delete(x); x=tr;}void upd(Seg *&x, int l, int r, int k, int v){ if(x==tr) x=new Seg; if(l==r){x->s+=v; return;} int mid=(l+r)>>1; if(k<=mid) upd(x->lc,l,mid,k,v); else upd(x->rc,mid+1,r,k,v); x->up(); if(!x->s) dec(x);}struct Node{ Node *lc, *rc; Seg *c, *s; int sz, v; void up(){sz=1+lc->sz+rc->sz;}}nd[MAXN], *st[MAXN], *root;void dfs(Node *x){ if(x==nd) return; dec(x->s); dfs(x->lc); st[top++]=x; dfs(x->rc);}void bu(Node *&x, int l, int r){ if(l>r){x=nd; return;} int mid=(l+r)>>1; x=st[mid]; bu(x->lc,l,mid-1); bu(x->rc,mid+1,r); x->up(); for(int i=l; i<=r; ++i) upd(x->s,0,MX,st[i]->v,1);}void rebu(Node *&x){top=0; dfs(x); bu(x,0,top-1);}void ins(Node *&x, int k, int v, int d=0){ if(x==nd){ x=&nd[++tot]; x->v=v; upd(x->c,0,MX,v,1); upd(x->s,0,MX,v,1); return; } upd(x->s,0,MX,v,1); int t=x->lc->sz+1; if(k<=t){ ins(x->lc,k,v,d+1); x->up(); if(x->lc->sz>=al*x->sz) rebu(x); }else{ ins(x->rc,k-t,v,d+1); x->up(); if(x->rc->sz>=al*x->sz) rebu(x); }}void md(Node *&x, int k, int v){ if(x==nd) return; int t=x->lc->sz; if(k==t+1){ ov=x->v; x->v=v; dec(x->c); upd(x->c,0,MX,v,1); }else if(k<=t) md(x->lc,k,v); else md(x->rc,k-t-1,v); upd(x->s,0,MX,ov,-1); upd(x->s,0,MX,v,1);}void qry(Node *x, int l, int r){ if(x==nd) return; if(L<=l&&r<=R){ tmp[nt++]=x->s; return; } int t=x->lc->sz; if(L<=l+t&&l+t<=R) tmp[nt++]=x->c; if(L
lc,l,l+t-1); if(l+t
rc,l+t+1,r);}int kth(int k){ int l=0, r=MX; while(l
>1; for(int i=0; i
lc->s; if(k<=t){ r=mid; for(int i=0; i
lc; }else{ l=mid+1; k-=t; for(int i=0; i
rc; } } return l;}void init(){ tr[0].lc=tr[0].rc=tr; for(int i=MAXM-1; i>0; --i) ST[TOP++]=tr+i; root=nd[0].lc=nd[0].rc=nd; nd[0].c=nd[0].s=tr; for(int i=1; i

转载于:https://www.cnblogs.com/will7101/p/6769268.html

你可能感兴趣的文章
hdu 3996
查看>>
python第三十九课——面向对象(二)之初始化属性
查看>>
python学习笔记之函数装饰器
查看>>
FEM计算2D瞬态热传导方程
查看>>
四年时光,匆匆而过
查看>>
【php】【psr】psr1 基础编码规范
查看>>
WAF SSI
查看>>
net.sf.json.JSONException: Object is null
查看>>
Java 实现word 中写入文字图片的解决方案
查看>>
码农常用软件
查看>>
(转载-学习)openstack中region、az、host aggregate、cell 概念
查看>>
内存对齐
查看>>
C++对象内存布局,this指针,对象作为参数,作为返回值
查看>>
BCB6 如何跨工程(Project)进行源码级调试
查看>>
proc near/far
查看>>
Dllmain的作用
查看>>
mov offset和lea的区别
查看>>
win7虚拟机安装
查看>>
C++中继承 声明基类析构函数为虚函数作用,单继承和多继承关系的内存分布
查看>>
C++编译器和连接器原理
查看>>