Dynamic Rankings

带修改的区间第K大其实就是先和静态区间第K大的操作一样。先建立一颗主席树, 然后再在树状数组的每一个节点开线段树(其实也是主席树,共用节点), 每次修改的时候都按照树状数组的方式去修改,并且修改那些地方。查询的时候就是查询原主席树+树状数组的值。

代码:

 #include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
//#define lson l,m,rt<<1
//#define rson m+1,r,rt<<1|1
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const LL mod = (int)1e9+;
const int N = ;
const int M = ;
int root[N], S[N], lson[M], rson[M], ll[N], rr[N], cnt[M];
int tot, t;
int lsz, rsz;
int a[N], b[N];
struct Node{
int l, r, op, k;
}A[N];
int Build(int l, int r){
int now = ++tot;
cnt[now] = ;
if(l < r){
int m = l+r >> ;
lson[now] = Build(l,m);
rson[now] = Build(m+,r);
}
return now;
}
int Update(int l, int r, int pre, int pos, int v){
int now = ++tot;
cnt[now] = cnt[pre] + v;
if(l < r){
int m = l+r >> ;
if(pos <= m){
rson[now] = rson[pre];
lson[now] = Update(l, m, lson[pre], pos, v);
}
else {
lson[now] = lson[pre];
rson[now] = Update(m+, r, rson[pre], pos, v);
}
cnt[now] = cnt[lson[now]] + cnt[rson[now]];
}
return now;
}
int Query(int l, int r, int L, int R, int k){
if(l == r) return l;
int num1 = cnt[lson[L]];
int num2 = cnt[lson[R]];
for(int i = ; i <= lsz; i++) num1 += cnt[lson[ll[i]]];
for(int i = ; i <= rsz; i++) num2 += cnt[lson[rr[i]]];
num2 -= num1;
int m = l+r >> ;
if(num2 >= k){
for(int i = ; i <= lsz; i++) ll[i] = lson[ll[i]];
for(int i = ; i <= rsz; i++) rr[i] = lson[rr[i]];
return Query(l, m, lson[L], lson[R], k);
}
else {
for(int i = ; i <= lsz; i++) ll[i] = rson[ll[i]];
for(int i = ; i <= rsz; i++) rr[i] = rson[rr[i]];
return Query(m+, r, rson[L], rson[R], k-num2);
}
}
int id(int x){
return lower_bound(b+, b++t, x) - b;
}
int lowbit(int x){
return x&(-x);
}
int main(){
int T;
scanf("%d", &T);
while(T--){
tot = t = ;
int n, m;
char s[];
scanf("%d%d", &n, &m);
for(int i = ; i <= n; i++) scanf("%d", &a[i]), b[++t] = a[i];
for(int i = ; i <= m; i++){
scanf("%s", s);
if(s[] == 'Q'){
A[i].op = ;
scanf("%d%d%d", &A[i].l, &A[i].r, &A[i].k);
}
else {
A[i].op = ;
scanf("%d%d", &A[i].l, &A[i].r);
b[++t] = A[i].r;
}
}
sort(b+, b++t);
int tmp = ;
for(int i = ; i <= t; i++)
if(b[i] != b[i-]) b[++tmp] = b[i];
t = tmp;
root[] = Build(, t);
for(int i = ; i <= n; i++){
root[i] = Update(, t, root[i-], id(a[i]), );
}
for(int i = ; i <= n; i++) S[i] = root[];
for(int i = ; i <= m; i++){
if(A[i].op == ){
lsz = rsz = ;
for(int j = A[i].l-; j; j-=lowbit(j)) ll[++lsz] = S[j];
for(int j = A[i].r; j; j-=lowbit(j)) rr[++rsz] = S[j];
printf("%d\n", b[Query(,t,root[A[i].l-], root[A[i].r], A[i].k)]);
}
else {
for(int j = A[i].l; j <= t; j += lowbit(j)) S[j] = Update(, t, S[j], id(a[A[i].l]), -);
for(int j = A[i].l; j <= t; j += lowbit(j)) S[j] = Update(, t, S[j], id(A[i].r), );
a[A[i].l] = A[i].r;
}
}
}
return ;
}

ZOJ 2112

ZOJ -2112 Dynamic Rankings 主席树 待修改的区间第K大的更多相关文章

  1. zoj 2112 Dynamic Rankings(主席树&amp;动态第k大)

    Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has ...

  2. ZOJ 2112 Dynamic Rankings(树状数组套主席树 可修改区间第k小)题解

    题意:求区间第k小,节点可修改 思路:如果直接用静态第k小去做,显然我更改一个节点后,后面的树都要改,这个复杂度太高.那么我们想到树状数组思路,树状数组是求前缀和,那么我们可以用树状数组套主席树,求出 ...

  3. ZOJ 2112 Dynamic Rankings(树状数组+主席树)

    题意 \(n\) 个数,\(m\) 个操作,每次操作修改某个数,或者询问某个区间的第 \(K\) 小值. \(1 \leq n \leq 50000\) \(1 \leq m \leq 10000\) ...

  4. 线段树专题2-(加强版线段树-可持续化线段树)主席树 orz! ------用于解决区间第k大的问题----xdoj-1216

    poj-2104(区间第K大问题) #include <iostream> #include <algorithm> #include <cstdio> #incl ...

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

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

  6. 主席树[可持久化线段树](hdu 2665 Kth number、SP 10628 Count on a tree、ZOJ 2112 Dynamic Rankings、codeforces 813E Army Creation、codeforces960F:Pathwalks )

    在今天三黑(恶意评分刷上去的那种)两紫的智推中,突然出现了P3834 [模板]可持久化线段树 1(主席树)就突然有了不详的预感2333 果然...然后我gg了!被大佬虐了! hdu 2665 Kth ...

  7. ZOJ 2112 Dynamic Rankings(动态区间第 k 大+块状链表)

    题目大意 给定一个数列,编号从 1 到 n,现在有 m 个操作,操作分两类: 1. 修改数列中某个位置的数的值为 val 2. 询问 [L, R] 这个区间中第 k 大的是多少 n<=50,00 ...

  8. 整体二分&cdq分治 ZOJ 2112 Dynamic Rankings

    题目:单点更新查询区间第k大 按照主席树的思想,要主席树套树状数组.即按照每个节点建立主席树,然后利用树状数组的方法来更新维护前缀和.然而,这样的做法在实际中并不能AC,原因即卡空间. 因此我们采用一 ...

  9. 整体二分(SP3946 K-th Number ZOJ 2112 Dynamic Rankings)

    SP3946 K-th Number (/2和>>1不一样!!) #include <algorithm> #include <bitset> #include & ...

随机推荐

  1. ubuntu下借助qt creator创建属于自己的共享库

    简介: 在 Windows 上,共享库由 .dll 表示:在 Linux 上,由 .so 表示. Shared Library的优势 共享库,又称动态库或so文件,顾名思义,它可以在可执行文件启动时加 ...

  2. 大型系列课程之-七夕告白之旅Electron篇

    上一篇分享了一下vbs的撩妹攻略,但细心的兄弟会发现,这种脚本式的攻城方案并不得心应手,有很多妹子害怕是病毒根本不敢点击,而且这个脚本界面风格也不漂亮,不能轻易打动妹子的心,怎么破,小编这次在为各位老 ...

  3. TensorFlow学习笔记——深层神经网络的整理

    维基百科对深度学习的精确定义为“一类通过多层非线性变换对高复杂性数据建模算法的合集”.因为深层神经网络是实现“多层非线性变换”最常用的一种方法,所以在实际中可以认为深度学习就是深度神经网络的代名词.从 ...

  4. 数据结构之队列C++版

    #include "stdafx.h"/* 队列是一种先进先出的线性表队列的核心是对头部和尾部索引的操作 如上图所示,当对头索引移动到最前面6,队尾又不不再末尾0的位置,那么如果不 ...

  5. Linux curl 常用示例

    本篇文章包含了curl的常用案例使用. 如果想了解curl选项的详细说明,请参考前一篇文章「Linux curl 命令详解」. 常见网页访问示例 基本用法 访问一个网页 curl https://ww ...

  6. js学习之数据类型

    js学习之数据类型 基础类型:number string boolean null undefined 引用类型:object array function undefined值是派生自null值的( ...

  7. springboot集成redis实现消息发布订阅模式-双通道(跨多服务器)

    基础配置参考https://blog.csdn.net/llll234/article/details/80966952 查看了基础配置那么会遇到一下几个问题: 1.实际应用中可能会订阅多个通道,而一 ...

  8. centos7之Python3.74安装

    安装版本:Python3.74 系统版本:centos7 系统默认安装Python2.7,保留. 安装/usr/bin/Python3 安装需要root权限. 安装Python3的准备工作: 1.安装 ...

  9. 阿里巴巴_java后端面经

    自我介绍不多说! 1 多线程有什么用?( 发挥多核CPU的优势 防止阻塞 便于建模 ) 2 怎么检测一个线程是否持有对象监视器( Thread类提供了一个holdsLock(Object obj)方法 ...

  10. 浅谈python中文件和文件夹的相关操作

    文件操作 文件的打开与关闭 打开文件 使用open(文件名,访问方式)函数,可以打开一个已存在的文件,或者创建一个新的文件. 示例如下: f = open('test.txt') # 访问方式可以省略 ...