[luogu P2617] Dynamic Rankings 带修主席树
带修改的主席树,其实这种,已经不能算作主席树了,因为这个没有维护可持久化的。。。
主席树直接带修改的话,由于这种数据结构是可持久化的,那么要相应改动,这个节点以后所有的主席树,这样单次修改,就达到n*log n 的复杂度
现在介绍这种待修改的主席树,本质上是用树状数组的区间查询维护的线段树,树状数组的每个点,都开一个权值线段树,维护的是lowbit(x)-x之间的数字的出现次数
这样我们相当于,把一个1-n权值线段树,用树状数组给砍成logn段,这样就非常方便。。。我们用树状数组遍历维护前缀和的过程,变成维护树的前缀的过程,这样单次维护的复杂度,大概为两个log,还是可以接受的
模版题
#include<bits/stdc++.h>
using namespace std;
const int maxx = 2e5+;
struct node{
int l,r,cnt;
}tree[maxx*];
struct query{
int l,r,k;
}que[maxx*];
int trl[maxx],trr[maxx],a[maxx],root[maxx];
int cnt,lenx,leny,n,sz;
vector<int>p;
void update(int l,int r,int pre,int &now,int pos,int w){
now=++cnt;
tree[now]=tree[pre];
tree[now].cnt+=w;
if (l==r)
return ;
int mid=(l+r)>>;
if (pos<=mid){
update(l,mid,tree[pre].l,tree[now].l,pos,w);
}else{
update(mid+,r,tree[pre].r,tree[now].r,pos,w);
}
}
/**查询区间第k大**/
int query(int l,int r,int k){
if(l==r)
return l;
int s=;
///查询区间个数
for (int i=;i<=lenx;i++){
s-=tree[tree[trl[i]].l].cnt;
}
for (int i=;i<=leny;i++){
s+=tree[tree[trr[i]].l].cnt;
}
int mid=(l+r)>>;
if(k<=s){
///把询问变成询问单点的左子树
for(int i=;i<=lenx;i++){
trl[i]=tree[trl[i]].l;
}
for(int i=;i<=leny;i++){
trr[i]=tree[trr[i]].l;
}
return query(l,mid,k);
}else {
///把询问变成询问单点的右子树
for(int i=;i<=lenx;i++){
trl[i]=tree[trl[i]].r;
}
for(int i=;i<=leny;i++){
trr[i]=tree[trr[i]].r;
}
return query(mid+,r,k-s);
}
}
int lowbit(int x){
return x&(-x);
}
void add(int x,int w){
int pos=lower_bound(p.begin(),p.end(),a[x])-p.begin()+;
for (int i=x;i<=n;i+=lowbit(i)){
update(,sz,root[i],root[i],pos,w);
}
}
int main(){
int q;
scanf("%d%d",&n,&q);
cnt=;
for (int i=;i<=n;i++){
scanf("%d",&a[i]);
p.push_back(a[i]);
}
for (int i=;i<=q;i++){
char op[];
scanf("%s",op);
if(op[]=='C'){
scanf("%d%d",&que[i].l,&que[i].r);
que[i].k=;
p.push_back(que[i].r);
}else{
scanf("%d%d%d",&que[i].l,&que[i].r,&que[i].k);
}
}
///把点全部离散排序
sort(p.begin(),p.end());
p.erase(unique(p.begin(),p.end()),p.end());
sz=p.size();
for (int i=;i<=n;i++){
add(i,);
}
for (int i=;i<=q;i++){
if (que[i].k){
lenx=;leny=;
for (int j=que[i].r;j;j-=lowbit(j)){
trr[++leny]=root[j];
}
for (int j=que[i].l-;j;j-=lowbit(j)){
trl[++lenx]=root[j];
}
printf("%d\n",p[query(,sz,que[i].k)-]);
}else{
///前缀中删除这个树的影响
add(que[i].l,-);
a[que[i].l]=que[i].r;
add(que[i].l,);
}
}
return ;
}
[luogu P2617] Dynamic Rankings 带修主席树的更多相关文章
- BZOJ1901 Dynamic Rankings|带修主席树
题目链接:戳我 其实我并不会做,于是看了题解 我们都知道主席树是利用前缀和记录历史版本来搞区间K大的一种数据结构.不过一般的主席树只能搞定静态区间第K大.如果带修怎么办呢? 想一下...单点修改+区间 ...
- 【BZOJ-1901】Dynamic Rankings 带修主席树
1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 7292 Solved: 3038[Su ...
- BZOJ 1901: Zju2112 Dynamic Rankings | 带修改主席树
题目: emmmm是个权限题 题解: 带修改主席树的板子题,核心思想是用树状数组维护动态前缀和的性质来支持修改 修改的时候修改类似树状数组一样进行logn个Insert 查询的时候同理,树状数组的方法 ...
- P2617 Dynamic Rankings(带修主席树)
所谓带修主席树,就是用树状数组的方法维护主席树的前缀和 思路 带修主席树的板子 注意数据范围显然要离散化即可 代码 #include <cstdio> #include <cstri ...
- 【BZOJ-1146】网络管理Network DFS序 + 带修主席树
1146: [CTSC2008]网络管理Network Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 3495 Solved: 1032[Submi ...
- Luogu P2617 Dynamic Rankings
带修主席树的模板,因为状态不好所以敲了很长时间,不过写完感觉能更好地理解主席树了. 核心其实就是树状数组套主席树,维护方法不再是以前的那种一步一修改,而是对于树状数组上的每一个点建立一棵权值线段树,然 ...
- 2018.07.01洛谷P2617 Dynamic Rankings(带修主席树)
P2617 Dynamic Rankings 题目描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i ...
- 2018.07.01 BZOJ3295: [Cqoi2011]动态逆序对(带修主席树)
3295: [Cqoi2011]动态逆序对 **Time Limit: 10 Sec Memory Limit: 128 MB Description 对于序列A,它的逆序对数定义为满足i<j& ...
- luogu P2617 Dynamic Rankings(主席树)
嘟嘟嘟 一句话题意:带修改区间第\(k\)小. 不修改都会,主席树板子.但是有修改就要比较深入的理解主席树了. 众所周知,主席树中以\(i\)为根的线段树维护的是\([1, i]\)这个前缀的权值,因 ...
随机推荐
- message d:\WEB_APP_QuChongFu\file\五月.xlsx (文件名、目录名或卷标语法不正确。)
原因是 文件名或文件夹名中不能出现以下字符:\ / : * ? " < > | 但是后台读取到的附件的文件路径就是这样的 网上大佬说了,这样处理 rep ...
- Django REST Framework之分页器
Django REST Framework提供了三种分页器: PageNumberPagination.基于Django Paginator封装,使得操作更方便,只需要做一些配置即可.分页方式:根据页 ...
- BIRT简介
BIRT(Business Intelligence and Reporting Tools,商业智能和报告工具,曾被安讯公司中国分公司译作百灵)项目是一个开源软件项目,其为富客户端应用和Web应用程 ...
- linux设置变量的三种方法
1在/etc/profile文件中添加变量对所有用户生效(永久的) 用VI在文件/etc/profile文件中增加变量,该变量将会对Linux下所有用户有效,并且是“永久生效”. 例如:编辑/etc/ ...
- 你知道forEach和each的区别吗?
要知道forEach和each的区别,你必须明白一点:forEach是js中的方法(针对数组),而each是jquery中的方法(针对jquery对象,即$( ) ).知道这一点,接下来我分别给举 ...
- 陈云川的OPENLDAP系列
前言 本 来,我应该准备一篇精彩的演说辞,从LDAP应用的方方面面讲起,细数LDAP在各种场合应用的成功案例,大肆渲染LDAP应用的辉煌前景,指出有多少机 构和组织的关键业务是建立在LDAP的基础上的 ...
- C++ UNREFERENCED_PARAMETER函数的作用
新建win32 application程序,会有这样一段代码 int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hP ...
- FatMouse' Trade (贪心)
#include <iostream> #include <stdio.h> #include <cstring> #include <cmath> # ...
- etree不存在解决方法
from lxml import html text=xxx//测试的html文本 etree = html.etree htmlDiv = etree.HTML(text) title = html ...
- python学习笔记09--线程、进程
本节内容 一.进程与线程的概念 1.1进程 1.2线程 1.3进程与线程的区别 二.线程 2.1启一个线程 2.2线程的2种调用方式 2.3 join 2.4 守护线程Daemon 2.5线程锁 2. ...