题意概述:带修改求区间第k大。

分析:

  我们知道不带修改的时候直接上主席树就可以了对吧?两个版本号里面的节点一起走在线段树上二分,复杂度是O((N+M)logN)。

  然而这里可以修改,主席树显然是凉了,但是注意到主席树的不带修改做法实际上是利用的差分的性质,即主席树本身实际上就是维护的一个前缀和一样的东西。想想普通的前缀和问题,我们求带修改前缀和是怎么做的?树状数组!于是我们用树状数组套线段树,树状数组里面每个点是一棵权值线段树,维护的是位置i前面lowbit(i)范围中的元素的权值信息,每一次更新的时候在logN棵线段树里修改,询问的时候logN棵线段树里一起走,在线段树上二分(树状数组套在外面写起来简单)。

  由于这个题对时间效率要求不是很高我就直接动态开点了没有离散化也没有卡常。实际上就是我比较懒

  时间复杂度O((N+M)logN^2)

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cctype>
using namespace std;
const int maxn=;
const int up=; int N,M,a[maxn];
struct mstruct{
static const int maxnode=;
static const int maxl=;
int rt[maxl],np,lc[maxnode],rc[maxnode],sz[maxnode];
int q1[maxl],q2[maxl],l1,l2;
mstruct(){ np=,sz[]=; memset(rt,,sizeof(rt)); }
int lowbit(int i){ return i&(-i); }
void pushup(int now){ sz[now]=sz[lc[now]]+sz[rc[now]]; }
void inupdate(int &now,int L,int R,int p,int v){
if(!now) now=++np,lc[now]=rc[now]=sz[now]=;
if(L==R){ sz[now]+=v; return; }
int m=L+R>>;
if(p<=m) inupdate(lc[now],L,m,p,v);
else inupdate(rc[now],m+,R,p,v);
pushup(now);
}
void update(int p,int v,bool c){
int i=p;
while(i<=N){
if(c) inupdate(rt[i],,up,a[p],-);
inupdate(rt[i],,up,v,);
i+=lowbit(i);
}
a[p]=v;
}
void mov(bool rig){
for(int i=;i<l1;i++) q1[i]=rig?rc[q1[i]]:lc[q1[i]];
for(int i=;i<l2;i++) q2[i]=rig?rc[q2[i]]:lc[q2[i]];
}
int inquery(int L,int R,int k){
if(L==R) return L;
int m=L+R>>,s1=,s2=;
for(int i=;i<l1;i++) s1+=sz[lc[q1[i]]];
for(int i=;i<l2;i++) s2+=sz[lc[q2[i]]];
if(k<=s2-s1){ mov(); return inquery(L,m,k); }
mov(); return inquery(m+,R,k-(s2-s1));
}
int query(int L,int R,int k){
l1=l2=;
int i=L; while(i) q1[l1++]=rt[i],i-=lowbit(i);
i=R; while(i) q2[l2++]=rt[i],i-=lowbit(i);
return inquery(,up,k);
}
}tt; void data_in()
{
scanf("%d%d",&N,&M);
for(int i=;i<=N;i++) scanf("%d",&a[i]);
for(int i=;i<=N;i++) tt.update(i,a[i],);
}
void work()
{
char op[];
int l,r,k,t;
for(int i=;i<=M;i++){
scanf("%s",op);
if(op[]=='C'){
scanf("%d%d",&l,&t);
tt.update(l,t,);
}
else if(op[]=='Q'){
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",tt.query(l-,r,k));
}
}
}
int main()
{
data_in();
work();
return ;
}

BZOJ 1901 Zju2112 Dynamic Rankings 树状数组套线段树的更多相关文章

  1. [BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】

    题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log^2 n). 线段树比树状数组麻 ...

  2. [BZOJ 3196] 213平衡树 【线段树套set + 树状数组套线段树】

    题目链接:BZOJ - 3196 题目分析 区间Kth和区间Rank用树状数组套线段树实现,区间前驱后继用线段树套set实现. 为了节省空间,需要离线,先离散化,这样需要的数组大小可以小一些,可以卡过 ...

  3. BZOJ.4553.[HEOI2016&TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点)

    题目链接:BZOJ 洛谷 \(O(n^2)\)DP很好写,对于当前的i从之前满足条件的j中选一个最大值,\(dp[i]=d[j]+1\) for(int j=1; j<i; ++j) if(a[ ...

  4. bzoj 3110: [Zjoi2013]K大数查询 树状数组套线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1384  Solved: 629[Submit][Stat ...

  5. [APIO2019] [LOJ 3146] 路灯 (cdq分治或树状数组套线段树)

    [APIO2019] [LOJ 3146] 路灯 (cdq分治或树状数组套线段树) 题面 略 分析 首先把一组询问(x,y)看成二维平面上的一个点,我们想办法用数据结构维护这个二维平面(注意根据题意这 ...

  6. P3157 [CQOI2011]动态逆序对(树状数组套线段树)

    P3157 [CQOI2011]动态逆序对 树状数组套线段树 静态逆序对咋做?树状数组(别管归并QWQ) 然鹅动态的咋做? 我们考虑每次删除一个元素. 减去的就是与这个元素有关的逆序对数,介个可以预处 ...

  7. bzoj3196 二逼平衡树 树状数组套线段树

    题目传送门 思路:树状数组套线段树模板题. 什么是树状数组套线段树,普通的树状数组每个点都是一个权值,而这里的树状数组每个点都是一颗权值线段树,我们用前缀差分的方法求得每个区间的各种信息, 其实关键就 ...

  8. 【序列操作IV】树状数组套线段树/树套树

    题目描述 给出序列 a1,a2,…,an(0≤ai≤109),有关序列的两种操作. 1. ai(1≤i≤n)变成 x(0≤x≤109). 2. 求 al,al+1,…,ar(1≤l≤r≤n)第 k(1 ...

  9. 2019南昌网络赛  I. Yukino With Subinterval 树状数组套线段树

    I. Yukino With Subinterval 题目链接: Problem Descripe Yukino has an array \(a_1, a_2 \cdots a_n\). As a ...

随机推荐

  1. T-SQL查询:WITH AS 递归计算某部门的所有上级机构或下级机构

    drop table #Area; CREATE TABLE #Area ( id INT NOT NULL, city_name NVARCHAR(100) NOT NULL, parent_id ...

  2. html5手机浏览器启动微信客户端支付实例

    html5手机浏览器启动微信客户端支付实例,外部浏览器html5微信支付技术,如何在手机浏览器微信支付,在微信客户端外的移动端网页使用微信支付 首先在微信支付官网https://pay.weixin. ...

  3. ElasticSearch优化系列四:ES的heap是如何被瓜分掉的

    以下分别解读几个我知道的内存消耗大户: Segment Memory Segment不是file吗?segment memory又是什么?前面提到过,一个segment是一个完备的lucene倒排索引 ...

  4. linux几个重要的组合键

    我们在用Windows系统时,有没有感觉快键键让我们工作更有效率,在Linux系统中仍有很好用的快捷键,这些快捷键可以辅助我们进行指令的编写与程序的中断呢,下面介绍几个经常用到的快捷键. 一.Tab- ...

  5. python格式化输出、逻辑表达式和字符编码

    格式化输出: %s  字符串占位符;%d 整数占位符 注意:如果前面有了占位符,那么后面所有的%都是占位,如果要输出“%”,需要使用转移符,即"%%" #定义三个变量 name = ...

  6. (数据科学学习手札55)利用ggthemr来美化ggplot2图像

    一.简介 R中的ggplot2是一个非常强大灵活的数据可视化包,熟悉其绘图规则后便可以自由地生成各种可视化图像,但其默认的色彩和样式在很多时候难免有些过于朴素,本文将要介绍的ggthemr包专门针对原 ...

  7. WPF几个基础概念的浅显理解

    1.逻辑树与视觉树 逻辑树在结构上与xaml文件对应 视觉树更细化,拆分到控件的每个组成部分 2.依赖属性与附加属性 依赖属性:就是自己自己没有属性值,而是通过Binding从数据源获得值,就是依赖在 ...

  8. 20155308 2016-2017-2 《Java程序设计》实验二 Java面向对象程序设计

    20155308 2016-2017-2 <Java程序设计>实验二 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UM ...

  9. Luogu1801_黑匣子_KEY

    题目传送门 借这道题练一下Treap和Splay的板子. code: #include <cstdio> #include <cstdlib> using namespace ...

  10. day7 RHCE

    6.配置本地邮件服务 在系统server0和desktop0上配置邮件服务,满足以下要求:这些系统不接收外部发送来的邮件这些系统上本地发送的任何邮件都会自动路由到 classroom.example. ...