BZOJ1901 Dynamic Rankings|带修主席树
题目链接:戳我
其实我并不会做,于是看了题解
我们都知道主席树是利用前缀和记录历史版本来搞区间K大的一种数据结构。不过一般的主席树只能搞定静态区间第K大。如果带修怎么办呢?
想一下。。。单点修改+区间查询,我们是否能想到树状数组呢?
那么思路就出来了。用树状数组来维护主席树的前缀和!!这里的主席树只需要维护对于每个节点所包含的值域区间中数的个数即可,不需要继承历史版本。
单次操作复杂度两个log,应该是稳稳的了。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 100010
using namespace std;
inline int read()
{
int f=1,x=0; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48); ch=getchar();}
return x*f;
}
int n,m,q_cnt,cnt,tot,cnt1,cnt2;
int a[MAXN],S[MAXN],rt[MAXN],tmp1[MAXN],tmp2[MAXN];
struct Node{int l,r,k,pos,t;}q[MAXN];
struct Node2{int ls,rs,v;}t[MAXN<<5];
inline void modify(int &now,int l,int r,int pos,int k)
{
if(!now) now=++tot;
t[now].v+=k;
if(l==r) return;
int mid=(l+r)>>1;
if(pos<=mid) modify(t[now].ls,l,mid,pos,k);
else modify(t[now].rs,mid+1,r,pos,k);
}
inline void pre_modify(int x,int k)
{
int pos=lower_bound(&S[1],&S[1+cnt],a[x])-S;
for(int i=x;i<=n;i+=i&(-i))
modify(rt[i],1,cnt,pos,k);
}
inline int query(int l,int r,int k)
{
if(l==r) {return S[l];}
int cur_ans=0;
for(int i=1;i<=cnt1;i++) cur_ans+=t[t[tmp1[i]].ls].v;
for(int i=1;i<=cnt2;i++) cur_ans-=t[t[tmp2[i]].ls].v;
int mid=(l+r)>>1;
if(cur_ans>=k)
{
for(int i=1;i<=cnt1;i++) tmp1[i]=t[tmp1[i]].ls;
for(int i=1;i<=cnt2;i++) tmp2[i]=t[tmp2[i]].ls;
return query(l,mid,k);
}
else
{
for(int i=1;i<=cnt1;i++) tmp1[i]=t[tmp1[i]].rs;
for(int i=1;i<=cnt2;i++) tmp2[i]=t[tmp2[i]].rs;
return query(mid+1,r,k-cur_ans);
}
}
inline void pre_query(int l,int r,int k)
{
cnt1=cnt2=0;
for(int i=r;i;i-=i&(-i)) tmp1[++cnt1]=rt[i];
for(int i=l;i;i-=i&(-i)) tmp2[++cnt2]=rt[i];
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) a[i]=read(),S[++cnt]=a[i];
for(int i=1;i<=m;i++)
{
char cur[10];
scanf("%s",cur);
if(cur[0]=='Q') q[i]=(Node){read()-1,read(),read(),0,0};
else q[i]=(Node){0,0,0,read(),read()},S[++cnt]=q[i].t;
}
sort(&S[1],&S[cnt+1]);
cnt=unique(&S[1],&S[cnt+1])-S-1;
for(int i=1;i<=n;i++) pre_modify(i,1);
for(int i=1;i<=m;i++)
{
if(q[i].k!=0)
{
pre_query(q[i].l,q[i].r,q[i].k);
printf("%d\n",query(1,cnt,q[i].k));
}
else
{
pre_modify(q[i].pos,-1);
a[q[i].pos]=q[i].t;
pre_modify(q[i].pos,1);
}
}
}
BZOJ1901 Dynamic Rankings|带修主席树的更多相关文章
- 【BZOJ-1901】Dynamic Rankings 带修主席树
1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 7292 Solved: 3038[Su ...
- [luogu P2617] Dynamic Rankings 带修主席树
带修改的主席树,其实这种,已经不能算作主席树了,因为这个没有维护可持久化的... 主席树直接带修改的话,由于这种数据结构是可持久化的,那么要相应改动,这个节点以后所有的主席树,这样单次修改,就达到n* ...
- 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 ...
- 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& ...
- bzoj1901: Zju2112 Dynamic Rankings(BIT套主席树)
带修改的题主席树不记录前缀,只记录单点,用BIT统计前缀. 对于BIT上每一个点建一棵主席树,修改和询问的时候用BIT跑,在主席树上做就行了. 3k4人AC的题#256...应该不算慢 #incl ...
- 带修主席树 洛谷2617 支持单点更新以及区间kth大查询
题目链接:https://www.luogu.com.cn/problem/P2617 参考博客:https://blog.csdn.net/dreaming__ldx/article/details ...
随机推荐
- axis2 webService开发指南(1)
参考文件:blog.csdn.net/IBM_hoojo http://hoojo.cnblogs.com/ 1 WebService简介 WebService让一个程序可以透明的调用互联网的程序,不 ...
- Excel另存为_有些Excel打开时会出现一些提示
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...
- Apache Flume的介绍安装及简单案例
概述 Flume 是 一个高可用的,高可靠的,分布式的海量日志采集.聚合和传输的软件.Flume 的核心是把数据从数据源(source)收集过来,再将收集到的数据送到指定的目的地(sink).为了保证 ...
- 启动和关闭MySQL服务
停止mysql服务,说来简单,但不知道的话,还真是挠头.在这和mysql入门的同学们共享:) 正确方法是,进入mysql的bin目录下,然后执行./mysqladmin -uroot -p shut ...
- C语言中static修饰符的意义
在C语言中,static通常有2种含义:1)定义变量的生命周期:2)定义变量或者函数的作用域. 变量的生命周期是指,相对于程序运行的进程生命周期,变量存在的时间段.变量的生命周期由变量的存储类型(位置 ...
- js setTimeout 和 setInterval 区别
setTimeout和setInterval的语法相同.它们都有两个参数,一个是将要执行的代码字符串,还有一个是以毫秒为单位的时间间隔,当过了那个时间段之后就将执行那段代码.不过这两个函数还是有区别的 ...
- noi2729 Blah数集
Blah数集 大数学家高斯小时候偶然间发现一种有趣的自然数集合Blah,对于以a为基的集合Ba定义如下: (1) a是集合Ba的基,且a是Ba的第一个元素: (2)如果x在集合Ba中,则2x+1和3x ...
- ACM暑假培训宣讲稿
(鞠躬)感谢大家的掌声! 我上台来作这次的宣讲,首先要感谢大家的捧场(当然,这是一句玩笑话),其实吧,我要感谢一下我们ACM班老大(班长),hjh队友,是他指派我来的,给了我这个宝贵的机会.最要感谢的 ...
- Smarty的循环
(1)section.sectionelse功能多,参数多.或许不是太实用.是smarty用来做循环操作的函数之一.(2)了解基本属性name和loop <section name=articl ...
- pageadmin去掉xxx
首先,屏蔽网页标题栏上的版权信息. 这个版本的信息在Incs目录下,我添加代码的文件是web_top.ascx,在它的最底下加入下面的代码. <script language="jav ...