BZOJ 3065 带插入区间K小值
http://www.lydsy.com/JudgeOnline/problem.php?id=3065
思路:替罪羊树套权值线段树。
当替罪羊树某个子树大于某个比利(比例)时就暴力重构,本题时间复杂度:O(nlog^3n)
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<vector>
#define alpha 0.75
#define N 10000005
int read(){
char ch=getchar();int t=,f=;
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
int tmp;
int n,m,sz,ans,root;
int v[],dfn[],rt[],ls[],rs[];
struct seg{int l,r,sum;}a[N];
std::vector<int>p,t,rec;
int newnode(){
if (!rec.size()) return ++sz;
else{
int k=rec.back();rec.pop_back();
return k;
}
}
void recliam(int &x){
if (!x) return;
rec.push_back(x);
recliam(a[x].l);recliam(a[x].r);
a[x].sum=;x=;
}
void insert(int &k,int l,int r,int val,int f){
if (!k) k=newnode();
if (l==r){a[k].sum+=f;return;}
int mid=(l+r)>>;
if (val<=mid) insert(a[k].l,l,mid,val,f);
else insert(a[k].r,mid+,r,val,f);
a[k].sum=a[a[k].l].sum+a[a[k].r].sum;
if (!a[k].sum) recliam(k);
}
void build(int &k,int l,int r){
int mid=(l+r)>>;
if (l>r) return;
if (l==r){
k=dfn[l];insert(rt[k],,,v[k],);return;
}
k=dfn[mid];
build(ls[k],l,mid-);build(rs[k],mid+,r);
for (int i=l;i<=r;i++)
insert(rt[k],,,v[dfn[i]],);
}
void del(int &x){
if (!x) return;recliam(rt[x]);
del(ls[x]);p.push_back(x);del(rs[x]);
x=;
}
void rebuild(int &x){
del(x);int s1=p.size();
for (int i=;i<=s1;i++) dfn[i]=p[i-];
build(x,,s1);
p.clear();
}
int modify(int k,int x,int val){
insert(rt[k],,,val,);
int t,L=a[rt[ls[k]]].sum;
if (L+==x){t=v[k];v[k]=val;}
else if (L>=x) t=modify(ls[k],x,val);
else t=modify(rs[k],x-L-,val);
insert(rt[k],,,t,-);
return t;
}
void query(int k,int l,int r){
int L=a[rt[ls[k]]].sum,R=a[rt[k]].sum;
if (l==&&r==R){t.push_back(rt[k]);return;}
if (l<=L+&&r>=L+)p.push_back(v[k]);
if (r<=L)query(ls[k],l,r);
else if (l>L+) query(rs[k],l-L-,r-L-);
else{
if (l<=L) query(ls[k],l,L);
if (R>L+) query(rs[k],,r-L-);
}
}
int solve_query(int L,int R,int K){
query(root,L,R);K--;
int l=,r=,s1=t.size(),s2=p.size();
while (l<r){
int mid=(l+r)>>,sum=;
for (int i=;i<s1;i++) sum+=a[a[t[i]].l].sum;
for (int i=;i<s2;i++)
if (p[i]>=l&&p[i]<=mid) sum++;
if (K<sum){
for (int i=;i<s1;i++) t[i]=a[t[i]].l;
r=mid;
} else{
for (int i=;i<s1;i++) t[i]=a[t[i]].r;
l=mid+;K-=sum;
}
}
t.clear();p.clear();
return l;
}
void insert(int &k,int x,int val){
if (!k){
k=++n;
insert(rt[k],,,val,);
v[k]=val;
return;
}
insert(rt[k],,,val,);
int L=a[rt[ls[k]]].sum;
if (L>=x) insert(ls[k],x,val);else insert(rs[k],x-L-,val);
if (a[rt[k]].sum*alpha>std::max((double)a[rt[ls[k]]].sum,(double)a[rt[rs[k]]].sum)){
if (tmp){
if (ls[k]==tmp) rebuild(ls[k]);
else rebuild(rs[k]);
tmp=;
}
}else tmp=k;
}
int main(){
n=read();
for (int i=;i<=n;i++) v[i]=read();
for (int i=;i<=n;i++) dfn[i]=i;
build(root,,n);
m=read();
char ch[];int x,y,K;
while (m--){
scanf("%s",ch);
x=read();y=read();x^=ans;y^=ans;
switch(ch[]){
case 'Q':K=read();K^=ans;ans=solve_query(x,y,K);printf("%d\n",ans);break;
case 'M':modify(root,x,y);break;
case 'I':tmp=;insert(root,x-,y);if (tmp){tmp=;rebuild(root);}break;
}
}
}
BZOJ 3065 带插入区间K小值的更多相关文章
- bzoj 3065: 带插入区间K小值 替罪羊树 && AC300
3065: 带插入区间K小值 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 1062 Solved: 253[Submit][Status] Des ...
- 【题解】BZOJ 3065: 带插入区间K小值——替罪羊树套线段树
题目传送门 题解 orz vfk的题解 3065: 带插入区间K小值 系列题解 一 二 三 四 惨 一开始用了一种空间常数很大的方法,每次重构的时候merge两颗线段树,然后无限RE(其实是MLE). ...
- BZOJ 3065 带插入区间K小值(sag套线段树)
3065: 带插入区间K小值 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 4696 Solved: 1527[Submit][Status][Di ...
- bzoj 3065: 带插入区间K小值(分块)
Description 从前有n只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力a[i].跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理性愉悦一下,查询区间k小值.他每次向它 ...
- BZOJ 3065 带插入区间K小值 (替罪羊树套线段树)
毒瘤题.参考抄自博客:hzwer 第一次写替罪羊树,完全是照着题解写的,发现这玩意儿好强啊,不用旋转每次都重构还能nlognnlognnlogn. 还有外面二分和里面线段树的值域一样,那么r = mi ...
- 3065: 带插入区间K小值_树套树_替罪羊树_权值线段树
经过周六一天,周一3个小时的晚自习,周二2个小时的疯狂debug,终于凭借自己切掉了这道树套树题. Code: #include <cstdio> #include <algorit ...
- 【BZOJ】3065: 带插入区间K小值
http://www.lydsy.com/JudgeOnline/problem.php?id=3065 题意:带插入.修改的区间k小值在线查询.(原序列n<=35000, 询问<=175 ...
- 【学习笔记】浅析平衡树套线段树 & 带插入区间K小值
常见的树套树 一般来说,在嵌套数据结构中,线段树多被作为外层结构使用. 但线段树毕竟是 静态 的结构,导致了一些不便. 下面是一个难以维护的例子: 带插入区间 \(k\) 小值问题 来源:Luogu ...
- [BZOJ3065]带插入区间K小值 解题报告 替罪羊树+值域线段树
刚了一天的题终于切掉了,数据结构题的代码真**难调,这是我做过的第一道树套树题,做完后感觉对树套树都有阴影了......下面写一下做题记录. Portal Gun:[BZOJ3065]带插入区间k小值 ...
随机推荐
- redis 集群
http://www.linuxidc.com/Linux/2015-08/121845.htm Redis3.0版本之后支持Cluster,具体介绍redis集群我就不多说,了解请看redis中文简 ...
- Android Scroller类的详细分析
尊重原创作者,转载请注明出处: http://blog.csdn.net/gemmem/article/details/7321910 Scroller这个类理解起来有一定的困难,刚开始接触Scrol ...
- Effect of Switchovers, Failovers, and Control File Creation on Backups
对dataguard 官方文档里面的这句话不理解,是否能给出一个样例说明: 10.2.0.5的版本号 Effect of Switchovers, Failovers, and Control Fil ...
- [转] GCC __builtin_expect的作用
http://blog.csdn.net/shuimuniao/article/details/8017971 将流水线引入cpu,可以提高cpu的效率.更简单的说,让cpu可以预先取出下一条指令,可 ...
- Effective C++ 总结(二)
四.设计与声明 条款18:让接口容易被正确使用,不易被误用 理想上,如果客户企图使用某个接口而却没有获得他所预期的行为,这个代码不该通过编译:如果代码通过了编译,它的行为就 ...
- sizeof操作符-结构体与类大小
导读 sizeof是C/C++一个难点,当在自定义类上应用sizeof操作符时,总会出现意想不到的结果,下面,我们就来探讨一下sizeof这个操作符! 目录 1. sizeof与strlen的区别 2 ...
- linux安装tomcat(转载:http://blog.csdn.net/zhuihunmiling/article/details/8977387)
在安装Tomcat之前需要安装j2sdk(Java 2 Software Development Kit),也就是JDK 1.安装JDK完毕. 2.安装Tomcat 1)下载apache-tomcat ...
- .NET aspx页面中的按钮无法响应事件
原因只有一个,页面中存在多个form标签.按Ctrl+F,找到多余的删掉即可
- Struts1 中$ 没有解析的问题
如果发现你的代码中,${name} 没有解析,就这样显示在页面上,排除错误的情况下 可能是你的jsp缺少一种属性isELIgnored="false" 加上就能够显示了 <% ...
- 开源的Android开发框架-------PowerFramework使用心得(一)总体介绍
PowerFramework是一款几乎囊括了所有Android基础功能的框架应用,这个框架目前是开源的,开发者可以在这个框架的基础上进行二次开发.结合开发者自己的UI设计,可以很快就能开发出具备基础应 ...