题解:

替罪羊树

(讲道理昨天讲课我一点都听不懂)

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的更多相关文章

  1. [BZOJ3065]带插入区间K小值 解题报告 替罪羊树+值域线段树

    刚了一天的题终于切掉了,数据结构题的代码真**难调,这是我做过的第一道树套树题,做完后感觉对树套树都有阴影了......下面写一下做题记录. Portal Gun:[BZOJ3065]带插入区间k小值 ...

  2. 【BZOJ3065】带插入区间K小值 替罪羊树+权值线段树

    [BZOJ3065]带插入区间K小值 Description 从前有n只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力a[i].跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理 ...

  3. bzoj3065: 带插入区间K小值

    无聊来写了下 一开始发现树高是O(n)的,然后就MLE了,进去看了下发现没有重构! 看了半天发现调用错了函数 然后进去又发现不满足sz = ch[0]->sz + ch[1]->sz + ...

  4. BZOJ3065(替罪羊树套线段树)

    以前看到这题都瑟瑟发抖,终于过了心情舒畅. 按下标为关键字建替罪羊树,每个结点开一个权值线段树,维护的这个结点代表的子树的信息. 这题还得垃圾回收,自己yy的,不知对不对.. #include < ...

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

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

  6. BZOJ3065 带插入区间K小值 || 洛谷P4278

    这是一道让我崩溃的题...... 然鹅洛谷上时限被改然后只有20分......好像所有人都被卡了(雾) 由于替罪羊树不是依靠旋转操作而是依靠暴力重构的方式维护树的平衡,所以我们可以考虑使用替罪羊树套区 ...

  7. 【函数式权值分块】【块状链表】bzoj3065 带插入区间K小值

    显然是块状链表的经典题.但是经典做法的复杂度是O(n*sqrt(n)*log^2(n))的,出题人明确说了会卡掉. 于是我们考虑每个块内记录前n个块的权值分块. 查询的时候差分什么的,复杂度就是O(n ...

  8. 「BZOJ3065」带插入区间第K小值 替罪羊树×线段树

    题目描述 从前有\(n\)只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力\(a_i\).跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理性愉悦一下,查询区间\(k\)小值.他 ...

  9. [bzoj3065] 带插入区间第k小值 [重量平衡树套线段树]

    题面 传送门 思路 发现强制在线了...... 本来可以树套树解决的问题,现在外层不能使用线段树了,拿什么替代呢? 我们需要一种支持单点插入.下套数据结构.数据结构上传合并复杂度最多单log,不能旋转 ...

随机推荐

  1. Django组件(二) Django之Form

    Forms组件概述 forms组件 -Django提供的用语数据校验和模板渲染的组件 -在项目中创建一个py文件 -1 写一个类继承Form -2 在类中写属性,写的属性,就是要校验的字段 -3 使用 ...

  2. JavaScript:Object属性方法

    Object的属性(firebug中没有找到) var pro={ city:"shanghai", list:[,,,,] } var Person=function(name, ...

  3. environment variable is too large 2047

    https://stackoverflow.com/questions/34491244/environment-variable-is-too-large-on-windows-10 方案1 Whe ...

  4. 论文笔记:Mastering the game of Go with deep neural networks and tree search

    Mastering the game of Go with deep neural networks and tree search Nature 2015  这是本人论文笔记系列第二篇 Nature ...

  5. Facebook广告API系列 3 Ads Management

    Facebook广告API系列 3 Facebook marketing API有三大组成部分: Audience Management Ads Management Ads Insights 本篇介 ...

  6. BZOJ 1005: [HNOI2008]明明的烦恼(prufer数列)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1005 题意: Description 自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标 ...

  7. MVC---- DataSet 页面遍历

    后台代码: public override ActionResult Index() { DataSet ab = custapp.GetCustomerFollows(); ViewData[&qu ...

  8. 非[无]root权限 服务器 下安装perl以及perl模块

    转载自http://www.zilhua.com 在本博客中,所有的软件安装都在服务器上,且无root权限.理论上适合所有的用户. 我的安装目录 cd /home/zilhua/software 1. ...

  9. Ubuntu 14.04 定时任务

    如何在Ubuntu上启动一个定时任务,使得可以定时删除机器上的日志 首先, #查看cron状态 service cron status   如果提示没有安装 #安装cron服务 apt-get ins ...

  10. 【Docker】性能测试监控平台搭建:InfluxDB+Grafana+Jmeter+cAdvisor

    前言 在做性能测试时,如果有一个性能测试结果实时展示的页面,可以极大的提高我们对系统性能表现的掌握程度,进而提高我们的测试效率.但是我们每次打开Jmeter都会有几个硕大的字提示别用GUI模式进行负载 ...