链接:https://www.luogu.org/problemnew/show/P2617

思路:

如果直接在主席树上修改的话,每次修改都会对后面所有的树造成影响,一次修改的复杂度就会变成 : n*logn,我们套上树状数组维护,每次就最多只用更新logn棵树,复杂度是:logn*logn,是可以接受的;

代码参考hzwer: http://hzwer.com/2835.html

实现代码;

#include<bits/stdc++.h>
using namespace std;
const int M = 2e5+;
int v[M],num[M*],has[M*];
int op[M],A[M],B[M],K[M],rt[M];
int sum[M*],ls[M*],rs[M*];
int L[],R[],a,b,tot,idx,k; int lowbit(int x){
return x&(-x);
} int find(int x){
int l = ,r = tot;
while(l <= r){
int mid = (l + r) >> ;
if(has[mid] < x) l = mid + ;
else r = mid - ;
}
return l;
} void update(int old,int &k,int p,int c,int l,int r){
k = ++idx;
ls[k] = ls[old],rs[k] = rs[old];
sum[k] = sum[old] + c;
if(l == r) return ;
int mid = (l + r) >> ;
if(p <= mid) update(ls[old],ls[k],p,c,l,mid);
else update(rs[old],rs[k],p,c,mid+,r);
} int query(int l,int r,int k){
if(l == r) return l;
int suml = ,sumr = ;
for(int i = ;i <= a;i ++) suml += sum[ls[L[i]]];
for(int i = ;i <= b;i ++) sumr += sum[ls[R[i]]];
int mid = (l + r) >> ;
if(sumr - suml >= k){
for(int i = ;i <= a;i ++) L[i] = ls[L[i]];
for(int i = ;i <= b;i ++) R[i] = ls[R[i]];
return query(l,mid,k);
}
else {
for(int i = ;i <= a;i ++) L[i] = rs[L[i]];
for(int i = ;i <= b;i ++) R[i] = rs[R[i]];
return query(mid+,r,k-(sumr-suml));
}
} int main()
{
int n,m,cnt = ;
scanf("%d%d",&n,&m);
for(int i = ;i <= n;i ++){
scanf("%d",&v[i]);
num[++cnt] = v[i];
}
char s[];
for(int i = ;i <= m;i ++){
scanf("%s",s);
scanf("%d%d",&A[i],&B[i]);
if(s[]=='Q') scanf("%d",&K[i]),op[i] = ;
else num[++cnt] = B[i];
}
sort(num+,num+cnt+);
has[++tot] = num[];
for(int i = ;i <= cnt;i ++){
if(num[i] != num[i-])
has[++tot] = num[i];
}
for(int i = ;i <= n;i ++){
int k = find(v[i]);
for(int j = i;j <= n;j += lowbit(j))
update(rt[j],rt[j],k,,,tot);
}
for(int i = ;i <= m;i ++){
if(op[i]){
a = ; b = ; A[i]--;
for(int j = A[i];j > ;j -= lowbit(j))
L[++a] = rt[j];
for(int j = B[i];j > ;j -= lowbit(j))
R[++b] = rt[j];
printf("%d\n",has[query(,tot,K[i])]);
}
else{
int k = find(v[A[i]]);
for(int j = A[i];j <= n;j += lowbit(j))
update(rt[j],rt[j],k,-,,tot);
v[A[i]] = B[i];
k = find(B[i]);
for(int j = A[i];j <= n;j += lowbit(j))
update(rt[j],rt[j],k,,,tot);
}
}
return ;
}

luogu P2617 Dynamic Rankings && bzoj 1901 (带修改区间第k大)的更多相关文章

  1. 洛谷P2617 Dynamic Rankings 主席树 单点修改 区间查询第 K 大

    我们将线段树套在树状数组上,查询前预处理出所有要一起移动的节点编号,并在查询过程中一起将这些节点移到左右子树上. Code: #include<cstdio> #include<cs ...

  2. 【ZOJ2112】【整体二分+树状数组】带修改区间第k大

    The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with t ...

  3. Dynamic Rankings——带修改区间第k大

    三种做法:1.整体二分: 二分mid 考虑小于mid的修改的影响 但是大于mid的修改可能会干掉小于mid的一些值 所以额外把一个修改变成一个值的删除和一个值的添加 这样就相互独立了! 整体二分,树状 ...

  4. luogu P2617 Dynamic Rankings(分块,n <= 1e4)

    嘟嘟嘟 带修改区间第k大. 然而某谷把数据扩大到了1e5,所以用分块现在只能得50分. 分块怎么做呢?很暴力的. 基本思想还是块内有序,块外暴力统计. 对于修改,直接重排修改的数所在块,时间复杂度O( ...

  5. luogu P2617 Dynamic Rankings(主席树)

    嘟嘟嘟 一句话题意:带修改区间第\(k\)小. 不修改都会,主席树板子.但是有修改就要比较深入的理解主席树了. 众所周知,主席树中以\(i\)为根的线段树维护的是\([1, i]\)这个前缀的权值,因 ...

  6. 少年,想学带修改主席树吗 | BZOJ1901 带修改区间第k小

    少年,想学带修改主席树吗 | BZOJ1901 带修改区间第k小 有一道题(BZOJ 1901)是这样的:n个数,m个询问,询问有两种:修改某个数/询问区间第k小. 不带修改的区间第k小用主席树很好写 ...

  7. [luogu P2617] Dynamic Rankings 带修主席树

    带修改的主席树,其实这种,已经不能算作主席树了,因为这个没有维护可持久化的... 主席树直接带修改的话,由于这种数据结构是可持久化的,那么要相应改动,这个节点以后所有的主席树,这样单次修改,就达到n* ...

  8. Luogu P2617 Dynamic Rankings

    带修主席树的模板,因为状态不好所以敲了很长时间,不过写完感觉能更好地理解主席树了. 核心其实就是树状数组套主席树,维护方法不再是以前的那种一步一修改,而是对于树状数组上的每一个点建立一棵权值线段树,然 ...

  9. Luogu P2617 Dynamic Rankings(整体二分)

    题目 动态区间第K小模板题. 一个非常可行的办法是BIT套动态开点权值SegTree,但是它跑的实在太慢了. 然后由于这题并没有强制在线,所以我们可以使用整体二分来吊打树套树. 当然如果强制在线的话就 ...

随机推荐

  1. iOS----------随机色

    #define KColorRandomColor [UIColor colorWithRed:arc4random()%255/255.0 green:arc4random()%255/255.0 ...

  2. C#字符串倒置函数的代码

    把内容过程比较常用的内容珍藏起来,下边内容内容是关于C#字符串倒置函数的内容. public static string Reverse(string ReverseString) { String ...

  3. C#监控指定目录的文件变化的代码

    如下的资料是关于C#监控指定目录的文件变化的代码. FileSystemWatcher watcher = new FileSystemWatcher();watcher.Path = @" ...

  4. 2019Java查漏补缺(一)

    看到一个总结的知识: 感觉很全面的知识梳理,自己在github上总结了计算机网络笔记就很累了,猜想思维导图的方式一定花费了作者很大的精力,特共享出来.原文:java基础思维导图 自己学习的查漏补缺如下 ...

  5. 调试工具gdb

    1.1 gdb符号调试器简介 gdb是一个用来调试C和C++程序的功能强大的调试器,它能在程序运行时观察程序的内部结构和内存的使用情况. gdb主要提供以下几种功能: 监视程序中变量值的变化 设置断点 ...

  6. LeetCode算法题-Shortest Unsorted Continuous Subarray(Java实现)

    这是悦乐书的第267次更新,第281篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第134题(顺位题号是581).给定一个整数数组,找到一个连续的子数组,按升序对该子数组 ...

  7. spingboot一键部署到阿里云(Cloud Toolkit工具)

    一般做法 一键部署工具   前些天在完成一个项目时候需要将springboot项目部署到服务器上, 以下是两种做法 前面介绍的是一般做法: 后面将介绍省去这些步骤的一键部署工具Cloud Toolki ...

  8. SystemTap Beginners Guide

    SystemTap 3.0 SystemTap Beginners Guide Introduction to SystemTap Edition 3.0   Red Hat, Inc. Don Do ...

  9. Java的动态代理

    什么是动态代理(dynamic proxy) 动态代理(以下称代理),利用Java的反射技术(Java Reflection),在运行时创建一个实现某些给定接口的新类(也称“动态代理类”)及其实例(对 ...

  10. linux下安装nodejs及npm

    转:https://www.cnblogs.com/wuyoucao/p/7011666.html 1.下载npm包 官网下载npm安装包,https://nodejs.org/en/,左边是稳定版右 ...