题解:

替罪羊树

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

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. openwrt的编译系统是如何生成squashfs文件系统的

    答:请看include/image.mk中的以下定义: define Image/mkfs/squashfs $(STAGING_DIR_HOST)/bin/mksquashfs4 $(call mk ...

  2. JavaScript:正则表达式 问号

    问号 1.?表示重复前面内容的0次或一次(但尽可能多重复) var reg=/abc?/g; var str="abcdabcaba"; console.log(str.match ...

  3. Open Source Log Management

    https://www.elastic.co/solutions/logging The Elastic Stack (sometimes known as the ELK Stack) is the ...

  4. git的软件安装

    1.Git for Winodws 1.*的版本   https://github.com/msysgit/msysgit/releases 2.*的版本   https://github.com/g ...

  5. [web开发] - 一些注解的解释

    @WebServlet替代了原本web.xml中配置的url拦截 可以直接在servlet上添加该注解,加入("/hello")类似的路径 但在controller层(Spring ...

  6. UVa 1395 苗条的生成树(Kruskal+并查集)

    https://vjudge.net/problem/UVA-1395 题意: 给出一个n结点的图,求苗条度(最大边减最小边的值)尽量小的生成树. 思路: 主要还是克鲁斯卡尔算法,先仍是按权值排序,对 ...

  7. POJ 3624 Charm Bracelet(0-1背包模板)

    http://poj.org/problem?id=3624 题意:给出物品的重量和价值,在重量一定的情况下价值尽可能的大. 思路:经典0-1背包.直接套用模板. #include<iostre ...

  8. # WinForm关闭窗体确认

    private void Lba_IE_Form_FormClosing(object sender, FormClosingEventArgs e) { if (MessageBox.Show(&q ...

  9. Linux基础※※※※连接XShell到Ubuntu 14.04 LTS

    参考链接: 博客链接1:http://blog.csdn.net/lichangzai/article/details/39379153 百度百科:http://baike.baidu.com/lin ...

  10. Python matplot画散列图

    同matlab一样,matplot也可画散列图scatter. import numpy as np import matplotlib.pyplot as plt #fig = plt.figure ...