ZOJ -2112 Dynamic Rankings 主席树 待修改的区间第K大
带修改的区间第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大的更多相关文章
- zoj 2112 Dynamic Rankings(主席树&动态第k大)
Dynamic Rankings Time Limit: 10 Seconds Memory Limit: 32768 KB The Company Dynamic Rankings has ...
- ZOJ 2112 Dynamic Rankings(树状数组套主席树 可修改区间第k小)题解
题意:求区间第k小,节点可修改 思路:如果直接用静态第k小去做,显然我更改一个节点后,后面的树都要改,这个复杂度太高.那么我们想到树状数组思路,树状数组是求前缀和,那么我们可以用树状数组套主席树,求出 ...
- ZOJ 2112 Dynamic Rankings(树状数组+主席树)
题意 \(n\) 个数,\(m\) 个操作,每次操作修改某个数,或者询问某个区间的第 \(K\) 小值. \(1 \leq n \leq 50000\) \(1 \leq m \leq 10000\) ...
- 线段树专题2-(加强版线段树-可持续化线段树)主席树 orz! ------用于解决区间第k大的问题----xdoj-1216
poj-2104(区间第K大问题) #include <iostream> #include <algorithm> #include <cstdio> #incl ...
- 洛谷P2617 Dynamic Rankings 主席树 单点修改 区间查询第 K 大
我们将线段树套在树状数组上,查询前预处理出所有要一起移动的节点编号,并在查询过程中一起将这些节点移到左右子树上. Code: #include<cstdio> #include<cs ...
- 主席树[可持久化线段树](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 ...
- ZOJ 2112 Dynamic Rankings(动态区间第 k 大+块状链表)
题目大意 给定一个数列,编号从 1 到 n,现在有 m 个操作,操作分两类: 1. 修改数列中某个位置的数的值为 val 2. 询问 [L, R] 这个区间中第 k 大的是多少 n<=50,00 ...
- 整体二分&cdq分治 ZOJ 2112 Dynamic Rankings
题目:单点更新查询区间第k大 按照主席树的思想,要主席树套树状数组.即按照每个节点建立主席树,然后利用树状数组的方法来更新维护前缀和.然而,这样的做法在实际中并不能AC,原因即卡空间. 因此我们采用一 ...
- 整体二分(SP3946 K-th Number ZOJ 2112 Dynamic Rankings)
SP3946 K-th Number (/2和>>1不一样!!) #include <algorithm> #include <bitset> #include & ...
随机推荐
- CountDownLatch实现多线程并发请求
package com.test; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Dat ...
- oracle的本地远程连接和配置
Oracle数据库的远程连接可以通过多种方式来实现,本文我们主要介绍四种远程连接的方法和注意事项,并通过示例来说明,接下来我们就开始介绍. 第一种情况: 若oracle服务器装在本机上,那就不多说了, ...
- jboss6.1安装配置
Jboss6.1的用途,配置,使用详解 一..简介: JBoss是全世界开发者共同努力的成果,一个基于J2EE的开放源代码的应用服务器因为JBoss代码遵循LGPL许可,你可以在任何商业应用中免费使 ...
- MySQL操作命令梳理(1)
一.索引 1.创建索引 索引的创建可以在CREATE TABLE语句中进行,也可以单独用CREATE INDEX或ALTER TABLE来给表增加索引.以下命令语句分别展示了如何创建主键索引(PRIM ...
- JavaFX 集成 Sqlite 和 Hibernate 开发爬虫应用
目录 [隐藏] 0.1 前言: 0.2 界面 0.3 Maven 环境 0.4 项目结构 0.5 整合 Hibernate 0.5.1 SQLiteDialect.java 数据库方言代码 0.5.2 ...
- SpringBoot 使用JPA时解决no session的方法
1.在application.yml中添加 spring.jpa.open-in-view: true 2.在使用查询的方法添加 @Transactional
- 0x03 前缀和与差分
前缀和 [例题]BZOJ1218 激光炸弹 计算二位前缀和,再利用容斥原理计算出答案即可. #include <iostream> #include <cstdio> #inc ...
- 最简单的DWR例子
什么是DWR? DWR是一个Open Source的 java项目.DWR可以让JavaScript调用运行在Web服务器里面的JAVA程序.简单一点或者专业一点就是Easy AJAX for JAV ...
- Java——反射:运行时的类信息
RTTI的使用 如果不知道某个对象的确切类型,RTTI会告诉我们,但是有一个限制:这个类型在编译时必须已知,这样才能使用RTTI识别它,并利用这些信息做一些有用的事情. 2.什么情况下需要反射 假设 ...
- .netcore持续集成测试篇之Xunit结合netcore内存服务器发送post请求
系列目录 Web项目中,很多与用户数据交互的请求都是Post请求,想必大家都用过HttpClient构造过post请求,这里并不对HttpClient做详细介绍,只介绍一些常用的功能.并结合AutoF ...