Link:

BZOJ 1901 传送门

Solution:

带修改主席树的模板题

对于静态区间第$k$大直接上主席树就行了

但加上修改后会发现修改时复杂度不满足要求了:

去掉/增加第$i$位上的值时要更新$i...n$间所有的主席树,使得单次修改的复杂度达到$n*log(n)$

可以将原来的主席树看成前缀数组

求某一段时尚可直接差分,但涉及到修改时就要改动$O(n)$级别的节点了

这时想到优化前缀和问题的树状数组

如果将原来的每一棵主席树看作树状数组上的点并利用$lowbit()$修改/求值

这样就能每次改动$log(n)$棵主席树,从而将复杂度降到$log(n)^2$

实现中先离散化,对于每一次修改先去掉删除原值,再添加新值就好啦

注意修改时要先记录所有需要的节点并一起移动,对于$k$大问题无法单独计算

Tip:

1、此时每棵线段树已经不再具有主席树的性质了:每次修改在前者基础上增加一条链

其实现在每棵线段树就是在自己原基础上修改,准确地说就是树状数组套动态开点权值线段树

2、好像此类动态开点线段树的空间复杂度我不太会算……

此题好像$O(n*log(n))$就够用了……

Code:

#include <bits/stdc++.h>

using namespace std;
const int MAXN=;
char s[];
struct Query{int i,j,k;}q[MAXN];
//内存开大,好像这题n*log(n)就够了
struct PrTree{int ls,rs,cnt;}seg[];
int n,m,dat[MAXN],rt[MAXN],L[],R[],dsp[MAXN<<],tot,totl,totr,cnt;
inline int lowbit(int x){return x&(-x);}
//PrTree
void Update(int &cur,int pos,int val,int l,int r)
{
if(!cur) cur=++cnt;
seg[cur].cnt+=val;
if(l==r) return;int mid=(l+r)>>;
if(pos<=mid) Update(seg[cur].ls,pos,val,l,mid);
else Update(seg[cur].rs,pos,val,mid+,r);
} int Query(int k,int l,int r)
{
if(l==r) return l;
int sum=,mid=(l+r)>>;
for(int i=;i<=totl;i++) sum-=seg[seg[L[i]].ls].cnt;
for(int i=;i<=totr;i++) sum+=seg[seg[R[i]].ls].cnt;
if(sum>=k)
{
for(int i=;i<=totl;i++) L[i]=seg[L[i]].ls;
for(int i=;i<=totr;i++) R[i]=seg[R[i]].ls;
return Query(k,l,mid);
}
else
{
for(int i=;i<=totl;i++) L[i]=seg[L[i]].rs;
for(int i=;i<=totr;i++) R[i]=seg[R[i]].rs;
return Query(k-sum,mid+,r);
}
}
//BIT
void upd(int x,int val)
{
int pos=lower_bound(dsp+,dsp+tot+,dat[x])-dsp;
for(int i=x;i<=n;i+=lowbit(i))
Update(rt[i],pos,val,,tot);
} int qry(int l,int r,int k)
{
totl=totr=;
for(int i=l-;i;i-=lowbit(i)) L[++totl]=rt[i];
for(int i=r;i;i-=lowbit(i)) R[++totr]=rt[i];
return dsp[Query(k,,tot)];
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%d",&dat[i]),dsp[++tot]=dat[i];
for(int i=;i<=m;i++)
{
scanf("%s%d%d",s,&q[i].i,&q[i].j);
if(s[]=='Q') scanf("%d",&q[i].k);
else dsp[++tot]=q[i].j;
}
sort(dsp+,dsp+tot+);
tot=unique(dsp+,dsp+tot+)-dsp-; for(int i=;i<=n;i++) upd(i,);
for(int i=;i<=m;i++)
{
if(q[i].k) printf("%d\n",qry(q[i].i,q[i].j,q[i].k));
else upd(q[i].i,-),dat[q[i].i]=q[i].j,upd(q[i].i,);
}
return ;
}

[BZOJ 1901] Dynamic Rankings的更多相关文章

  1. bzoj 1901 Dynamic Rankings (树状数组套线段树)

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MB Description 给定一个含有n个数的序列a[1] ...

  2. [BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】

    题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log^2 n). 线段树比树状数组麻 ...

  3. BZOJ.1901.Dynamic Rankings(线段树套平衡树 Splay)

    题目链接or Here 题意:n个数,有两个操作:1.修改某个数为v:2.询问一段区间第k小的数 如果没有修改,则可以用线段树,每个节点P[a,b]存储大小为b-a+1的数组,代表其中的数 同时,这个 ...

  4. BZOJ.1901.Dynamic Rankings(树状数组套主席树(动态主席树))

    题目链接 BZOJ 洛谷 区间第k小,我们可以想到主席树.然而这是静态的,怎么支持修改? 静态的主席树是利用前缀和+差分来求解的,那么对于每个位置上的每棵树看做一个点,拿树状数组更新. 还是树状数组的 ...

  5. BZOJ.1901.Dynamic Rankings(整体二分)

    题目链接 BZOJ 洛谷 (以下是口胡) 对于多组的询问.修改,我们可以发现: 假设有对p1,p2,p3...的询问,在这之前有对p0的修改(比如+1),且p0<=p1,p2,p3...,那么我 ...

  6. BZOJ 1901 Dynamic Rankings 树董事长

    标题效果:间隔可以改变k少 我的两个天树牌主席... 隔断Count On A Tree 之后我一直认为,随着树的主席的变化是分域林木覆盖率可持久段树. .. 事实上,我是误导... 尼可持久化线段树 ...

  7. BZOJ 1901 Dynamic Rankings (整体二分+树状数组)

    题目大意:略 洛谷传送门 这道题在洛谷上数据比较强 貌似这个题比较常见的写法是树状数组套主席树,动态修改 我写的是整体二分 一开始的序列全都视为插入 对于修改操作,把它拆分成插入和删除两个操作 像$C ...

  8. bzoj 1901: Zju2112 Dynamic Rankings(树套树)

    1901: Zju2112 Dynamic Rankings 经典的带改动求区间第k小值问题 树套树模板,我是用的线段树套splay实现的,并且用的数组模拟的,所以可能空间略大,bzoj过了,zoj过 ...

  9. BZOJ 1901 Zju2112 Dynamic Rankings

    树阵主席设置树.维护间隔动态K大. .. ZOJ到空间太小,太大,仅仅能到BZOJ上交 1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memor ...

随机推荐

  1. vue_router添加点击事件

    1.在vue学习中遇到给router-link 标签添加事件@click .@mouseover等无效的情况 原来的代码: <router-link to='/SelectPage' @clic ...

  2. 常见网络命令之Ping命令

    前言:计算机网络老师要求我们自己总结一下常见的网络命,然后上课可以上去讲一下这些命令使用,像我这么听话的好学生,肯定是照老师要求,认真的总结了一下,总结的过程中,我发现网上已经有的资源讲的都不是很详细 ...

  3. 2017-2018-1 20179205《Linux内核原理与设计》第十周作业

    <Linux内核原理与设计>第十周作业 教材17.19.20章学习及收获 1.在Linux以及所有unix系统中,设备被分为以下三种:块设备(blkdev)以块为单位寻址,通过块设备节点来 ...

  4. C后端设计开发 - 第3章-气功-原子锁线程协程

    正文 第3章-气功-原子锁线程协程 后记 如果有错误, 欢迎指正. 有好的补充, 和疑问欢迎交流, 一块提高. 在此谢谢大家了. 童话镇 - http://music.163.com/#/m/song ...

  5. 批量导出文件名 另存为bat文件

    @echo offdir /b *.* > 导出的文件名.txtexit

  6. EXT入门学习

    今天,对EXT做了一下初步的了解,了解了一些基本用的函数.窗体对象.表单.文本域.按钮,一些基本的函数我列了出来,写了个登陆的demo,是根据别人的例子模仿出来的,见谅哈. 基本函数 Ext.onRe ...

  7. FTP webReq.ContentType异常的处理

    FtpWebRequest webReq; webReq = (FtpWebRequest)FtpWebRequest.Create(new Uri(updateFileUrl)); FtpWebRe ...

  8. linux命令(43):cal命令

    cal命令可以用来显示公历(阳历)日历.公历是现在国际通用的历法,又称格列历,通称阳历.“阳历”又名“太阳历”,系以地球绕行太阳一周为一年,为西方各国所通用,故又名“西历”. 1.命令格式: cal  ...

  9. [水煮 ASP.NET Web API2 方法论](12-1)创建 OData

    问题 怎样用在 Web API 中创建 OData 服务. 解决方案 对于我们来说,在 Web API 中使用 OData最简单的方式就是使用 ASP.NET 模板来创建Odata Controlle ...

  10. git-全家桶

    关于git,网上一片赞美之声,我就不多说啥了,用过才知道,多好. 没有了解过的朋友,可以去大神廖雪峰传送门看看,我就是通过那里学会的基础,再次感谢大神无私的奉献!!! 下面分四个章节: 基础操作(其实 ...