[luogu2617]Dynamic Rankings
题面在这里
description
动态区间第\(k\)大
data range
\]
solution
前置技能:主席树,静态区间第\(k\)大
注意到主席树的区间维护是通过前缀和来实现的,
修改时需要对所有前缀进行修改,一次复杂度是\(O(nlogn)\),显然会\(TLE\)
树套树(树状数组套线段树???)
于是我们想到把主席树的前缀和维护改成树状数组维护
这样树状数组的每一个节点都代表的是一些权值线段树的前缀和
修改
对于树状数组上要修改的每一棵权值线段树进行修改(需要线段树动态开点),
每次加\(lowbit\)后直接在对应的权值线段树上删原点+插新点即可
需要修改\(O(logn)\)棵权值线段树,时间复杂度为\(O(log^2n)\)
查询
这里我们通过树状数组知道了区间\([l,r]\)的整棵权值线段树
在权值线段树上进行二分;
注意前缀\([1,l]\)和前缀\([1,r]\)在树套树上对应的权值线段树的数量可能不同,
于是我们需要在递归的同时保存这\(O(logn)\)个节点的位置
需要查询\(O(logn)\)棵权值线段树,时间复杂度为\(O(log^2n)\)
那么这道题目我们就很开心地做完啦
code
#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cstring>
#include<complex>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define lowbit(x) (x&-x)
#define pub push_back
#define puf push_front
#define pob pop_back
#define pof pop_front
#define RG register
#define il inline
using namespace std;
typedef unsigned long long ull;
typedef vector<int>VI;
typedef long long ll;
typedef double dd;
const dd eps=1e-10;
const int mod=1e8;
const int N=20010;
il ll read(){
RG ll data=0,w=1;RG char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
return data*w;
}
il void file(){
freopen(".in","r",stdin);
freopen(".out","w",stdout);
}
int n,m,len,a[N],o[N],cnt[2][N],rt[N],tot;char c;
struct query{int opt;int l,r,k;int p,t;}Q[N];
struct node{int v,ls,rs;}t[N*400];
#define mid ((l+r)>>1)
ll query(int l,int r,int k){
if(l==r)return l;RG int sum=0;
for(RG int i=1;i<=cnt[0][0];i++){
sum-=t[t[cnt[0][i]].ls].v;
}
for(RG int i=1;i<=cnt[1][0];i++){
sum+=t[t[cnt[1][i]].ls].v;
}
if(k<=sum){
for(RG int i=1;i<=cnt[0][0];i++)
cnt[0][i]=t[cnt[0][i]].ls;
for(RG int i=1;i<=cnt[1][0];i++)
cnt[1][i]=t[cnt[1][i]].ls;
return query(l,mid,k);
}
else{
for(RG int i=1;i<=cnt[0][0];i++)
cnt[0][i]=t[cnt[0][i]].rs;
for(RG int i=1;i<=cnt[1][0];i++)
cnt[1][i]=t[cnt[1][i]].rs;
return query(mid+1,r,k-sum);
}
}
il void query_tree(int l,int r,int k){
cnt[0][0]=cnt[1][0]=0;
for(RG int i=l-1;i;i-=lowbit(i))
cnt[0][++cnt[0][0]]=rt[i];
for(RG int i=r;i;i-=lowbit(i))
cnt[1][++cnt[1][0]]=rt[i];
printf("%d\n",o[query(1,len,k)]);
}
void modify(int &now,int l,int r,int p,int val){
if(!now)now=++tot;t[now].v+=val;if(l==r)return;
if(p<=mid)modify(t[now].ls,l,mid,p,val);
else modify(t[now].rs,mid+1,r,p,val);
}
il void modify_tree(int p,int val){
RG int x=lower_bound(o+1,o+len+1,a[p])-o;
for(RG int i=p;i<=n;i+=lowbit(i)){
modify(rt[i],1,len,x,val);
}
}
int main()
{
len=n=read();m=read();
for(RG int i=1;i<=n;i++)o[i]=a[i]=read();
for(RG int i=1;i<=m;i++){
c=0;while(c!='Q'&&c!='C')c=getchar();
Q[i].opt=(c=='Q');
if(c=='Q'){
Q[i].l=read();Q[i].r=read();Q[i].k=read();
}
else {Q[i].p=read();Q[i].t=read();o[++len]=Q[i].t;}
}
sort(o+1,o+len+1);len=unique(o+1,o+len+1)-o-1;
for(RG int i=1;i<=n;i++)modify_tree(i,1);
for(RG int i=1;i<=m;i++)
if(!Q[i].opt){
modify_tree(Q[i].p,-1);
a[Q[i].p]=Q[i].t;
modify_tree(Q[i].p,1);
}
else{query_tree(Q[i].l,Q[i].r,Q[i].k);}
return 0;
}
[luogu2617]Dynamic Rankings的更多相关文章
- [Luogu2617]Dynamic Rankings(整体二分)
Luogu 动态区间第K大的整体二分解法 之前学主席树的时候就做了这道题(明明是树套树不是主席树啊),码量挺大而且调了我一个晚上.换成整体二分我半个小时就写完了而且一A. 写起来就是爽. 其实原理很简 ...
- [BZOJ1901][luogu2617]Dynamic Rankings(树状数组+主席树)
题面 单点修改,区间求第k大 分析 首先,这道题卡权值线段树套treap的做法,所以只能用主席树做 对于静态的查询,root[i]对应的主席树的区间[l,r]保存的是a[1]~a[i]有多少个值落在区 ...
- 「luogu2617」Dynamic Rankings
「luogu2617」Dynamic Rankings 传送门 树套树直接上树状数组套主席树,常数很大就是了. 树套树参考代码: /*-------------------------------- ...
- BZOJ 1901: Zju2112 Dynamic Rankings[带修改的主席树]【学习笔记】
1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 7143 Solved: 2968[Su ...
- [bzoj1901][zoj2112][Dynamic Rankings] (整体二分+树状数组 or 动态开点线段树 or 主席树)
Dynamic Rankings Time Limit: 10 Seconds Memory Limit: 32768 KB The Company Dynamic Rankings has ...
- [BZOJ1901]Zju2112 Dynamic Rankings
[BZOJ1901]Zju2112 Dynamic Rankings 试题描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i ...
- ZOJ 2112 Dynamic Rankings(动态区间第 k 大+块状链表)
题目大意 给定一个数列,编号从 1 到 n,现在有 m 个操作,操作分两类: 1. 修改数列中某个位置的数的值为 val 2. 询问 [L, R] 这个区间中第 k 大的是多少 n<=50,00 ...
- BZOJ-1901 Zju2112 Dynamic Rankings 函数式线段树 套 树状数组+离线处理
1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MB Submit: 6058 Solved: 2521 [Su ...
- ZOJ 2112 Dynamic Rankings(主席树の动态kth)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2112 The Company Dynamic Rankings ...
随机推荐
- JS高级. 02 面向对象、创建对象、构造函数、自定义构造函数、原型
面向对象的三大特性: 封装 a) 把一些属性和方法装到一个对象里 2. 继承 a) js中的继承是指: 一个对象没有一些方法和属性,而另一个对象有 把另一个个对象的属性和方法,拿过来自己用, ...
- Hadoop(23)-Yarn资源调度器
Yarn是一个资源调度平台,负责为运算程序提供服务器运算资源,相当于一个分布式的操作系统平台,而MapReduce等运算程序则相当于运行于操作系统之上的应用程序 1. Yarn工作机制 机制详解 第1 ...
- 虚拟机服务没有启动的 CentOS 和 Ubuntu 无法上网
测试用 vmware 安装 OSX,安装补丁时要停止 vmware 的服务.如下图: 结果忘记启动了,导致 centos\ubuntu 等所有虚拟机都无法上网...所有的 启动这四个服务后,一切恢复正 ...
- Ruby字符串的一些方法
最近因为公司需求开始看ruby,先从ruby的基本数据类型开始看 看到ruby的字符串类型string,发现ruby中的字符串单双引号是不一样的,这点和Python有那么点不一样 主要是我们对字符串进 ...
- MongoDB入门---简介
最近呢,刚好有一些时间,所以就学习了一下新的数据库类型MongoDB.要想了解这个MongoDB,我们首先需要了解一个概念,那就是nosql(not only sql).一下就是官方的概念: NoSQ ...
- centos下搭建svn服务器端/客户端
1.安装 yum install subversion httpd mod_dav_svn 2.创建仓库存储代码 mkdir /var/repos svnadmin create /var/repos ...
- Memcached Hash算法
本文来自网易云社区 作者:吕宗胜 Hash算法 1. Memcached Hash介绍 我们在前面的文章中已经介绍过了Memcached的内存管理方式,LRU的策略.由于Memcached的数据存储方 ...
- jmeter常用的内置变量
1. vars API:http://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterVariables.html vars.get(& ...
- 「日常训练」 Mike and Fun (CFR305D2B)
题意(CodeForces 548B) 每次对01矩阵中的一位取反,问每次操作后,单列中最长连续1的长度. 分析 非常非常简单,但是我当时训练的时候WA了四次...无力吐槽了,人间 不值得.jpg 代 ...
- Python简要标准库(5)
hashlib Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 基本的生成MD密匙的函数 import hashlib md5 = hashlib.md5() md5.up ...