题目传送门

题解

orz vfk的题解

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

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

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

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

代码

#include <bits/stdc++.h>
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<l+t) qry(x->lc,l,l+t-1);if(l+t<R) qry(x->rc,l+t+1,r);
}
int kth(int k){int l=0, r=MX;while(l<r){int t=0, mid=(l+r)>>1;for(int i=0; i<nt; ++i) t+=tmp[i]->lc->s;if(k<=t){r=mid;for(int i=0; i<nt; ++i) tmp[i]=tmp[i]->lc;}else{l=mid+1; k-=t;for(int i=0; i<nt; ++i) tmp[i]=tmp[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<MAXN; ++i){nd[i].c=nd[i].s=tr;nd[i].lc=nd[i].rc=nd;nd[i].sz=1; }for(int i=1; i<=N; ++i){upd(nd[i].c,0,MX,A[i],1);st[top++]=nd+i; nd[i].v=A[i];}bu(root,0,top-1); tot=N;
}
int main(){fread(BUF, 1, MAXB, stdin);rd(N);for(int i=1; i<=N; ++i) rd(A[i]);init(); rd(M);int last=0;while(M--){char ch=rc();int x,y,k; rd(x),rd(y);x^=last; y^=last;if(ch=='Q'){L=x, R=y;rd(k); k^=last;nt=0; qry(root,1,N);printf("%d\n", last=kth(k));}else if(ch=='M')md(root,x,y);else if(ch=='I')ins(root,x,y),N++;}return 0;
}

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

【题解】BZOJ 3065: 带插入区间K小值——替罪羊树套线段树相关推荐

  1. P4278 带插入区间K小值

    题目链接 题目描述 快捷版题意:带插入.修改的区间k小值在线查询. 输入格式 第一行一个正整数nnn,表示原来有nnn只跳蚤排成一行做早操. 第二行有nnn个用空格隔开的非负整数,从左至右代表每只跳蚤 ...

  2. 【bzoj3065】: 带插入区间K小值 详解——替罪羊套函数式线段树

    不得不说,做过最爽的树套树---- 由于有了区间操作,我们很容易把区间看成一棵平衡树,对他进行插入,那么外面一层就是平衡树了,这就与我们之前所见到的不同了.我们之前所见到的大多数是线段树套平衡树而此题 ...

  3. BZOJ-3065 带插入区间K小值

    替罪羊树套权值线段树,其中替罪羊树可以满足插入的操作. #include <cstdlib> #include <cstdio> #include <algorithm& ...

  4. 【BZOJ 4605】崂山白花蛇草水 替罪羊树套线段树

    外层是借鉴了kd-tree的替罪羊里层是线段树,插入就是正常插入+拍扁重建,查询的时候,我们就像树状数组套线段树一样操作在替罪羊中找到的线段树根节点,但是对于在kd-tree查找过程中遇到的单点,我们 ...

  5. 【XSY2720】区间第k小 整体二分 可持久化线段树

    题目描述 给你你个序列,每次求区间第\(k\)小的数. 本题中,如果一个数在询问区间中出现了超过\(w\)次,那么就把这个数视为\(n\). 强制在线. \(n\leq 100000,a_i<n ...

  6. bzoj 3489 A simple rmq problem——主席树套线段树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题解:http://www.itdaan.com/blog/2017/11/24/9b ...

  7. bzoj 3217 ALOEXT 替罪羊树套trie树

    感觉又刚了一遍带插入区间k小值... 这题写个替罪羊练一下.其实应该可以用重量平衡的treap套trie. 带插入维护一段区间的trie和次小值. 区间次小值随便维护,区间trie呢? 我会做!替罪羊 ...

  8. BZOJ.4553.[HEOI2016TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点)

    题目链接:BZOJ 洛谷 \(O(n^2)\)DP很好写,对于当前的i从之前满足条件的j中选一个最大值,\(dp[i]=d[j]+1\) for(int j=1; j<i; ++j)if(a[j ...

  9. 【luogu3834】【模板】可持久化线段树 2(主席树),静态区间第K小值

    problem solution 题目:有n个数,多次询问一个区间[L,R]中第k小的值是多少. 思路: 查询[1,n]中的第k小值: 先对数据进行离散化,然后按值域建立线段树,线段树中维护某个值域中 ...

最新文章

  1. 伺服电机常用参数设置_6个步骤教你如何快速调试伺服电机
  2. ramebufferobject工程说明
  3. 虚拟云服务器 网站备案,云虚拟主机可以做备案吗
  4. php 读取文件的所有图片格式,扣丁学堂PHP培训简述PHP如何读取文件夹下所有图片、文件-php文件...
  5. DEBUG模式下,视频丢包严重;RELEASE就好了
  6. 413.等差数列划分
  7. 中国软件服务业政策和形势_赵小凡
  8. python numpy库下载_Numpy库的下载与安装总结
  9. 代码质量 权威精选植根于开发实践的最佳读物
  10. R语言使用gbm包的gbm函数拟合梯度提升机回归模型:使用predict函数和训练好的模型进行预测推理、计算回归模型的评估指标MAE、MSE、RMSE、R方等指标
  11. linux -m32,32位gcc和64位gcc与-m32选项有什么区别?
  12. 2021年全球消费级音频产品行业调研及趋势分析报告
  13. Emlog程序CYP音乐主题模板源码
  14. win7资源管理器中输入ftp站点跳转到浏览器
  15. js 原生cookie封装
  16. 自动化测试之单元测试框架
  17. 小程序开发-准备工作
  18. github中clone代码到本地与直接下载压缩包的区别
  19. Aspose.Words实用教程:如何处理文档分段——Aspose.Words中的分段
  20. 新建tag 查看本地Tag 查看远端Tag 基于远端Tag新建分支 删除远端Tag 等操作

热门文章

  1. Go语言的错误异常处理机制及其应用
  2. IDEA集成Docker插件实现一键自动打包部署微服务项目
  3. 2022-2028年中国TAC薄膜行业市场全景评估及投资前景规划报告
  4. 【C#实践】详解三层转七层:登录
  5. 预见未来丨机器学习:未来十年研究热点
  6. 微信架构 支付架构(下)
  7. 无监督域对抗算法:ICCV2019论文解析
  8. C++ 复制构造函数或者拷贝构造函数
  9. xlrd.biffh.XLRDError: Unsupported format, or corrupt file: Expected BOF record; found b‘b\x14#e\xbc\
  10. INSTALL_FAILED_USER_RESTRICTED