【题意】带修改的查询区间第k小

【算法】树状数组套可持久化线段树

【题解】对于树状数组上的每个节点,维护可持久化权值线段树(节点为权值),从而达到查询前缀和的目的。

对于每次修改,在待修改线段树基础上运用可持久化性质来修改,先删除原数字,再加入新数字

注意记录修改后的原数字,方便后来删除。

★注意区分权值范围和数组范围的区别!!!

复杂度O(n log2n)。

注意点全部标注在代码中,细节巨多。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
using namespace std;
int read()
{
char c;int s=,t=;
while(!isdigit(c=getchar()))if(c=='-')t=-;
do{s=s*+c-'';}while(isdigit(c=getchar()));
return s*t;
}
const int maxn=;
struct tree{int l,r,sum;}t[];//空间开大!!!100w都过不去啊。。。
char s[];
int cnt1,cnt2,a1[maxn],a2[maxn],a[maxn],b1[maxn],b2[maxn],b3[maxn],n,m,root[maxn],tot,c[maxn*],sz=; void insert(int l,int r,int x,int &y,int v,int c){
y=++sz;//设置新节点!!!
t[y]=t[x];t[y].sum+=c;
if(l==r)return;
int mid=(l+r)>>;
if(v<=mid)insert(l,mid,t[x].l,t[y].l,v,c);
else insert(mid+,r,t[x].r,t[y].r,v,c);
}
int ask(int l,int r,int v){
if(l==r)return l;
int sum=;
for(int i=;i<=cnt1;i++)sum-=t[t[a1[i]].l].sum;
for(int i=;i<=cnt2;i++)sum+=t[t[a2[i]].l].sum;
int mid=(l+r)>>;
if(sum>=v){
for(int i=;i<=cnt1;i++)a1[i]=t[a1[i]].l;
for(int i=;i<=cnt2;i++)a2[i]=t[a2[i]].l;
return ask(l,mid,v);
}
else{
for(int i=;i<=cnt1;i++)a1[i]=t[a1[i]].r;
for(int i=;i<=cnt2;i++)a2[i]=t[a2[i]].r;
return ask(mid+,r,v-sum);//转入右边要减去左边的
}
} int lowbit(int x){return x&(-x);}
void modify(int x,int k,int p){for(int i=x;i<=n;i+=lowbit(i))insert(,tot,root[i],root[i],k,p);}
//分清,tot是权值线段树范围,n是数组范围
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
a[i]=read();
c[++tot]=a[i];
}
for(int i=;i<=m;i++){
scanf("%s%d%d",s,&b1[i],&b2[i]);
if(s[]=='Q')b3[i]=read();
else c[++tot]=b2[i];
}
sort(c+,c+tot+);
tot=unique(c+,c+tot+)-c-;
for(int i=;i<=n;i++)a[i]=lower_bound(c+,c+tot+,a[i])-c;
for(int i=;i<=m;i++)if(!b3[i])b2[i]=lower_bound(c+,c+tot+,b2[i])-c;
for(int i=;i<=n;i++)modify(i,a[i],);
for(int i=;i<=m;i++){
if(b3[i]){
cnt1=;cnt2=;
for(int j=b1[i]-;j>=;j-=lowbit(j))a1[++cnt1]=root[j];
for(int j=b2[i];j>=;j-=lowbit(j))a2[++cnt2]=root[j];//用根啊老铁
printf("%d\n",c[ask(,tot,b3[i])]);//询问给的是离散化后的值,要还原
}
else{
modify(b1[i],a[b1[i]],-);
a[b1[i]]=b2[i];
modify(b1[i],b2[i],);
}
}
return ;
}

【BZOJ】1901: Zju2112 Dynamic Rankings的更多相关文章

  1. 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树状数组套主席树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1901 首先还是吐槽时间,我在zoj交无限tle啊!!!!!!!!我一直以为是程序错了啊啊啊啊啊啊. ...

  2. 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树套树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1901 这题调了我相当长的时间,1wa1a,我是第一次写树套树,这个是树状数组套splay,在每个区间 ...

  3. 【函数式权值分块】【分块】bzoj1901 Zju2112 Dynamic Rankings

    论某O(n*sqrt(n))的带修改区间k大值算法. 首先对序列分块,分成sqrt(n)块. 然后对权值分块,共维护sqrt(n)个权值分块,对于权值分块T[i],存储了序列分块的前i块的权值情况. ...

  4. 【分块】bzoj1901 Zju2112 Dynamic Rankings

    区间k大,分块大法好,每个区间内存储一个有序表. 二分答案,统计在区间内小于二分到的答案的值的个数,在每个整块内二分.零散的暴力即可. 还是说∵有二分操作,∴每个块的大小定为sqrt(n*log2(n ...

  5. 【基数排序】bzoj1901 Zju2112 Dynamic Rankings

    论NOIP级别的n²算法…… 跟分块比起来,理论上十万的数据只慢4.5倍左右的样子…… #include<cstdio> #include<algorithm> using n ...

  6. BZOJ 1901 Zju2112 Dynamic Rankings

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

  7. BZOJ 1901: Zju2112 Dynamic Rankings[带修改的主席树]【学习笔记】

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 7143  Solved: 2968[Su ...

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

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

  9. Bzoj 1901: Zju2112 Dynamic Rankings 树套树,线段树,平衡树,Treap

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 6471  Solved: 2697[Su ...

随机推荐

  1. 关于双系统下Ubuntu不能访问Windows中某个盘的问题

    1.问题描述   在Ubuntu系统下访问Windows系统中磁盘时出现无法访问的情况,具体如下显示:   该问题为磁盘挂载错误,需要进行修复. 2.解决办法   (1)打开终端:如果没有安装ntfs ...

  2. vue-cli脚手架搭建

    我们使用vue-cli来搭建整个项目,vue-cli就是一个脚手架,步骤很简单,输入几个命令之后就会生成整个项目,里面包括了webpack.ESLint.babel很多配置等等,省了很多事 Vue+ ...

  3. [转帖] 部分收费的Oracle JDK VS 完全免费的OpenJDK

    来源: http://www.flammulina.com/2018/10/28/%E9%83%A8%E5%88%86%E6%94%B6%E8%B4%B9%E7%9A%84oracle-jdk-vs- ...

  4. 有一个集合,判断集合里有没有“world”这个元素,如果有,添加“javaee”

    // 有一个集合,判断集合里有没有“world”这个元素,如果有,添加“javaee” List list = new ArrayList(); list.add("world") ...

  5. webgl glsl

    GLSL是什么? GLSL是运行在GPU上的着色器语言 GLSL有自己的语法,跟js有些不同. GLSL是一个强类型的语言,所以在写着器语言时,必须要用强类型,强类型,强类型,强类型 GLSL是着色器 ...

  6. js get selected text

    js get selected text https://stackoverflow.com/questions/3170648/how-to-get-javascript-select-boxs-s ...

  7. Spring Cloud构建微服务架构

    Dalston版本 由于Brixton和Camden版本的教程已经停止更新,所以笔者计划在2017年上半年完成Dalston版本的教程编写(原计划完成Camden版本教程,但由于写了两篇Dalston ...

  8. 【前端学习笔记03】JavaScript对象相关方法及封装

    //Object.create()创建对象 var obj = Object.create({aa:1,bb:2,cc:'c'}); obj.dd = 4; console.log(obj.cc); ...

  9. [十二]SpringBoot 之 servlet

    Web开发使用 Controller 基本上可以完成大部分需求,但是我们还可能会用到 Servlet.Filter.Listener.Interceptor 等等. 当使用spring-Boot时,嵌 ...

  10. [codeforces696B]Puzzles

    B. Puzzles time limit per test  1 second memory limit per test 256 megabytes input standard input ou ...