bzoj3065
题解:
替罪羊树
(讲道理昨天讲课我一点都听不懂)
alpha取到0.75比较好(当然啦可能其他的更好)
每当不满足条件的时候就重构
代码:
#include<bits/stdc++.h>
using namespace std;
const double alpha=0.75;
const int N=,M=;
int tmp,n,m,sz,lastans,root,v[M],dfn[M],rt[M],ls[M],rs[M];
struct seg{int l,r,sum;}a[N];
vector<int> rec,t,p;
inline int newnode()
{
if (!rec.size())return ++sz;
else
{
int k=rec.back();
rec.pop_back();
return k;
}
}
void reclaim(int &x)
{
if (!x)return;
rec.push_back(x);
reclaim(a[x].l);
reclaim(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)reclaim(k);
}
void build(int &k,int l,int r)
{
if (l>r)return;
if (l==r)
{
k=dfn[l];
insert(rt[k],,,v[k],);
return;
}
int mid=(l+r)>>;
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;
reclaim(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>max(a[rt[ls[k]]].sum,a[rt[rs[k]]].sum))
{
if (tmp)
{
if (ls[k]==tmp)rebuild(ls[k]);
else rebuild(rs[k]);
tmp=;
}
}
else tmp=k;
}
int main()
{
scanf("%d",&n);
for (int i=;i<=n;i++)scanf("%d",&v[i]);
for (int i=;i<=n;i++)dfn[i]=i;
build(root,,n);
scanf("%d",&m);
char s[];
int x,y,k;
while (m--)
{
scanf("%s",&s);
scanf("%d%d",&x,&y);
x^=lastans;y^=lastans;
if (s[]=='Q')
{
scanf("%d",&k);
k^=lastans;
lastans=solve_query(x,y,k);
printf("%d\n",lastans);
}
if (s[]=='M')modify(root,x,y);
if (s[]=='I')
{
tmp=;
insert(root,x-,y);
if (tmp)
{
tmp=;
rebuild(root);
}
}
}
}
bzoj3065的更多相关文章
- [BZOJ3065]带插入区间K小值 解题报告 替罪羊树+值域线段树
刚了一天的题终于切掉了,数据结构题的代码真**难调,这是我做过的第一道树套树题,做完后感觉对树套树都有阴影了......下面写一下做题记录. Portal Gun:[BZOJ3065]带插入区间k小值 ...
- 【BZOJ3065】带插入区间K小值 替罪羊树+权值线段树
[BZOJ3065]带插入区间K小值 Description 从前有n只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力a[i].跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理 ...
- bzoj3065: 带插入区间K小值
无聊来写了下 一开始发现树高是O(n)的,然后就MLE了,进去看了下发现没有重构! 看了半天发现调用错了函数 然后进去又发现不满足sz = ch[0]->sz + ch[1]->sz + ...
- BZOJ3065(替罪羊树套线段树)
以前看到这题都瑟瑟发抖,终于过了心情舒畅. 按下标为关键字建替罪羊树,每个结点开一个权值线段树,维护的这个结点代表的子树的信息. 这题还得垃圾回收,自己yy的,不知对不对.. #include < ...
- 【bzoj3065】: 带插入区间K小值 详解——替罪羊套函数式线段树
不得不说,做过最爽的树套树———— 由于有了区间操作,我们很容易把区间看成一棵平衡树,对他进行插入,那么外面一层就是平衡树了,这就与我们之前所见到的不同了.我们之前所见到的大多数是线段树套平衡树而此题 ...
- BZOJ3065 带插入区间K小值 || 洛谷P4278
这是一道让我崩溃的题...... 然鹅洛谷上时限被改然后只有20分......好像所有人都被卡了(雾) 由于替罪羊树不是依靠旋转操作而是依靠暴力重构的方式维护树的平衡,所以我们可以考虑使用替罪羊树套区 ...
- 【函数式权值分块】【块状链表】bzoj3065 带插入区间K小值
显然是块状链表的经典题.但是经典做法的复杂度是O(n*sqrt(n)*log^2(n))的,出题人明确说了会卡掉. 于是我们考虑每个块内记录前n个块的权值分块. 查询的时候差分什么的,复杂度就是O(n ...
- 「BZOJ3065」带插入区间第K小值 替罪羊树×线段树
题目描述 从前有\(n\)只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力\(a_i\).跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理性愉悦一下,查询区间\(k\)小值.他 ...
- [bzoj3065] 带插入区间第k小值 [重量平衡树套线段树]
题面 传送门 思路 发现强制在线了...... 本来可以树套树解决的问题,现在外层不能使用线段树了,拿什么替代呢? 我们需要一种支持单点插入.下套数据结构.数据结构上传合并复杂度最多单log,不能旋转 ...
随机推荐
- Python3基础 __len__,__getitem__ 记录列表中元素访问的次数 定制不可变序列,下标字典
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- CSS布局总结及实际应用中产生的问题
布局初步 所谓布局,其实是指的将网页内容以一定的方式放到合适的位置上去. 布局的基本步骤: 1, 将“当前版面”以视觉上界限明显的方式进行划分若干个区块,划分只用两种方式: a) 上下结构:此时,只要 ...
- linux下安装与运行docker
写者环境: 1.lsb_release -a hello@hello:~$ lsb_release -aNo LSB modules are available.Distributor ID: Ubu ...
- 将DevExpress.Utils.ImageCollection变量的image导出
private void tspBtnExportExcel_Click(object sender, EventArgs e) { //暂时用来导出图片 string filePath = Syst ...
- LaTex: Undefined citation warnings 解决方法
参考 Undefined citations LaTex: Undefined citation warnings 解决方法 在使用TexMaker编译文献的时候,出现引用参考文献的问题: Packa ...
- UVa 10723 电子人的基因(LCS)
https://vjudge.net/problem/UVA-10723 题意: 输入两个A~Z组成的字符串,找一个最短的串,使得输入的两个串均是它的子序列,另外还需要统计长度最短的串的个数. 思路: ...
- UVa 12174 Shuffle(滑动窗口)
https://vjudge.net/problem/UVA-12174 题意: 你在听音乐播放器,它采用随机播放形式.随机播放的原理时先随机产生一个1~n的排列,然后就按这个排列顺序播放歌曲.播放完 ...
- python 加密与解密
加密算法分类 对称加密算法: 对称加密采用了对称密码编码技术,它的特点是文件加密和解密使用相同的密钥 发送方和接收方需要持有同一把密钥,发送消息和接收消息均使用该密钥. 相对于非对称加密,对称加密具有 ...
- pyqt 实现的俄罗斯方块
from PyQt5.QtWidgets import QMainWindow, QFrame, QDesktopWidget, QApplication from PyQt5.QtCore impo ...
- Jmeter 中对响应报文处理后断言用到BeanShell Assertion
Jmeter中常用的断言可以是Response Assertion 如果需要对响应报文中的某个字符串进行解码,对解码之后的值在进行断言要怎么做呢? 仔细观察一下,可以用下面俩个元件 Regular E ...