BZOJ3065:带插入区间K小值
浅谈树状数组与主席树:https://www.cnblogs.com/AKMer/p/9946944.html
题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=3065
去%了一发hzwer的博客学会的。
替罪羊树套线段树,外层维护位置,内层维护权值。
时间复杂度:\(O(nlog^2n)\)
空间复杂度:\(O(nlog^2n)\)
代码如下:
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
const double alpha=0.75;
const int maxn=7e4+5,maxsz=2e7;
char s[5];
int n,m,lstans;
int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
}
struct Segment_tree {
int tot;
vector<int>rub;
int sum[maxsz],ls[maxsz],rs[maxsz];
int newnode() {
if(rub.empty())return ++tot;
else {
int res=rub.back();rub.pop_back();
return res;
}
}
void change(int p,int l,int r,int pos,int v) {
while(1) {
sum[p]+=v;
if(l==r)return;
int mid=(l+r)>>1;
if(pos<=mid) {
if(!ls[p])ls[p]=newnode();
p=ls[p],r=mid;
}
else {
if(!rs[p])rs[p]=newnode();
p=rs[p],l=mid+1;
}
}
}
void recycle(int u) {
if(!u)return;
rub.push_back(u);
recycle(ls[u]),recycle(rs[u]);
sum[u]=ls[u]=rs[u]=0;
}
}T2;
struct TiZuiYang_tree {
vector<int>num;
int tot,root,cnt;
int son[maxn][2];
vector<int>::iterator it;
int rt[maxn],siz[maxn],tmp[maxn],a[maxn],id[maxn];
int build(int l,int r) {
if(r<l)return 0;
if(l==r) {
int u=id[l];son[u][0]=son[u][1]=0;
rt[u]=T2.newnode(),siz[u]=1;
T2.change(rt[u],0,70000,a[u],1);
return u;
}
int mid=(l+r)>>1,u=id[mid];
rt[u]=T2.newnode();siz[u]=1;
son[u][0]=build(l,mid-1);
son[u][1]=build(mid+1,r);
siz[u]+=siz[son[u][0]]+siz[son[u][1]];
for(int i=l;i<=r;i++)T2.change(rt[u],0,70000,a[id[i]],1);
return u;
}
void find(int u,int l,int r) {
if(l==1&&r==siz[u]) {tmp[++cnt]=rt[u];return;}
int sz=siz[son[u][0]];
if(l<=sz+1&&r>=sz+1)num.push_back(a[u]);
if(r<=sz)find(son[u][0],l,r);
else if(l>sz+1)find(son[u][1],l-sz-1,r-sz-1);
else {
if(l<=sz)find(son[u][0],l,sz);
if(r>sz+1)find(son[u][1],1,r-sz-1);
}
}
int query(int l,int r,int rk) {
num.clear(),cnt=0,find(root,l,r);
int L=0,R=70000;
while(L!=R) {
int res=0,mid=(L+R)>>1;
for(int i=1;i<=cnt;i++)
res+=T2.sum[T2.ls[tmp[i]]];
for(it=num.begin();it!=num.end();it++)
if(*it>=L&&(*it)<=mid)res++;
if(res>=rk) {
for(int i=1;i<=cnt;i++)
tmp[i]=T2.ls[tmp[i]];
R=mid;
}
else {
for(int i=1;i<=cnt;i++)
tmp[i]=T2.rs[tmp[i]];
L=mid+1;rk-=res;
}
}
return L;
}
int change(int u,int pos,int x) {
T2.change(rt[u],0,70000,x,1);
int sz=siz[son[u][0]],res;
if(sz+1==pos) {res=a[u];a[u]=x;}
else if(sz>=pos)res=change(son[u][0],pos,x);
else res=change(son[u][1],pos-sz-1,x);
T2.change(rt[u],0,70000,res,-1);
return res;
}
void insert(int &u,int rk,int v) {
if(!u) {
u=++tot;rt[u]=T2.newnode();
T2.change(rt[u],0,70000,v,1);
siz[u]=1;a[u]=v;return;
}
T2.change(rt[u],0,70000,v,1);
int sz=siz[son[u][0]];siz[u]++;
if(sz>=rk)insert(son[u][0],rk,v);
else insert(son[u][1],rk-sz-1,v);
}
void dfs_rebuild(int u) {
if(!u)return;
dfs_rebuild(son[u][0]);
T2.recycle(rt[u]);
id[++cnt]=u;rt[u]=0;
dfs_rebuild(son[u][1]);
}
void find_rebuild(int &u,int rk) {
if(alpha*siz[u]<max(siz[son[u][0]],siz[son[u][1]])) {
cnt=0;dfs_rebuild(u);u=build(1,cnt);
return;
}
if(siz[son[u][0]]>=rk)find_rebuild(son[u][0],rk);
if(rk>siz[son[u][0]]+1)find_rebuild(son[u][1],rk-siz[son[u][0]]-1);
}
}T1;
int main() {
T1.tot=n=read();
for(int i=1;i<=n;i++)
T1.id[i]=i,T1.a[i]=read();
T1.root=T1.build(1,n);
m=read();
for(int i=1;i<=m;i++) {
scanf("%s",s+1);
if(s[1]=='Q') {
int l=read()^lstans,r=read()^lstans,k=read()^lstans;
lstans=T1.query(l,r,k);printf("%d\n",lstans);
}
if(s[1]=='M') {
int pos=read()^lstans,x=read()^lstans;
T1.change(T1.root,pos,x);
}
if(s[1]=='I') {
int pos=read()^lstans,x=read()^lstans;
T1.insert(T1.root,pos-1,x);
T1.find_rebuild(T1.root,pos);
}
}
return 0;
}
BZOJ3065:带插入区间K小值的更多相关文章
- [BZOJ3065]带插入区间K小值 解题报告 替罪羊树+值域线段树
刚了一天的题终于切掉了,数据结构题的代码真**难调,这是我做过的第一道树套树题,做完后感觉对树套树都有阴影了......下面写一下做题记录. Portal Gun:[BZOJ3065]带插入区间k小值 ...
- BZOJ3065 带插入区间K小值 || 洛谷P4278
这是一道让我崩溃的题...... 然鹅洛谷上时限被改然后只有20分......好像所有人都被卡了(雾) 由于替罪羊树不是依靠旋转操作而是依靠暴力重构的方式维护树的平衡,所以我们可以考虑使用替罪羊树套区 ...
- 【函数式权值分块】【块状链表】bzoj3065 带插入区间K小值
显然是块状链表的经典题.但是经典做法的复杂度是O(n*sqrt(n)*log^2(n))的,出题人明确说了会卡掉. 于是我们考虑每个块内记录前n个块的权值分块. 查询的时候差分什么的,复杂度就是O(n ...
- bzoj3065: 带插入区间K小值
无聊来写了下 一开始发现树高是O(n)的,然后就MLE了,进去看了下发现没有重构! 看了半天发现调用错了函数 然后进去又发现不满足sz = ch[0]->sz + ch[1]->sz + ...
- 【BZOJ3065】带插入区间K小值 替罪羊树+权值线段树
[BZOJ3065]带插入区间K小值 Description 从前有n只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力a[i].跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理 ...
- 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). ...
- 3065: 带插入区间K小值_树套树_替罪羊树_权值线段树
经过周六一天,周一3个小时的晚自习,周二2个小时的疯狂debug,终于凭借自己切掉了这道树套树题. Code: #include <cstdio> #include <algorit ...
- BZOJ 3065 带插入区间K小值(sag套线段树)
3065: 带插入区间K小值 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 4696 Solved: 1527[Submit][Status][Di ...
- 【学习笔记】浅析平衡树套线段树 & 带插入区间K小值
常见的树套树 一般来说,在嵌套数据结构中,线段树多被作为外层结构使用. 但线段树毕竟是 静态 的结构,导致了一些不便. 下面是一个难以维护的例子: 带插入区间 \(k\) 小值问题 来源:Luogu ...
随机推荐
- 每门课由平时成绩和考试成绩组成,满分为r。现在他知道每门课的平时成绩为ai ,若想让这门课的考试成绩多拿一分的话,小v要花bi 的时间复习,不复习的话当然就是0分。同时我们显然可以发现复习得再多也不会拿到超过满分的分数。为了拿到奖学金,小v至少要花多少时间复习。
遇到问题要常思考为什么,做这道题的时候,要注意给定的数据范围. 第一行三个整数n,r,avg(n大于等于1小于等于1e5,r大于等于1小于等于1e9,avg大于等于1小于等于1e6),接下来n行,每行 ...
- coreos 安装
一.挂载coreos 镜像 引导live-cd 配置初始化coreos 系统 网卡和密码 进入live版系统后呈现这个状态 #任意编辑一个.network 文件,文件名随意,该文件不存在需自己创建 s ...
- 【转】win7 任务计划 任务映像已损坏或篡改(异常来自HRESULT:0x80041321)
请这样操作:1. 以管理员身份运行命令提示符并执行命令chcp 437schtasks /query /v | find /i "ERROR: Task cannot be loaded:& ...
- Drupal 主题的表现形式
1.template.php /** * Implements hook_theme(). */ function yourtheme_theme($existing, $type, $theme ...
- Xcode iphone模拟器运行不流畅
xcode该需要多高的配置......把这个取消就好了
- python 基础 9.3 mysql 数据操作
#/usr/bin/python #coding=utf-8 #@Time :2017/11/21 0:20 #@Auther :liuzhenchuan #@File :mysql 数据操作 ...
- 谁能举个通俗易懂的例子告诉我IAAS,SAAS,PAAS的区别?【转自知乎】
是时候祭出这篇吃货文章了: ———————————————————— ———————————————————— ———————————————————— &amp;amp;amp;lt ...
- kibana 查询语法
根据某个字段查询 精确匹配: agent:"Mozilla/5.0" 如果不带双引号,只要包含指定值就可以搜索到 agent:Mozilla/5.0 如果是数值类型没有以上区别 数 ...
- SASL mechanism
<property> <name>hive.spark.client.rpc.sasl.mechanisms</name> <value>DIGEST- ...
- visio_action
bug---沟通效率不能为负值!! https://blogs.office.com/en-us/2012/11/05/containers-and-callouts-in-visio/?eu=tru ...