题目描述

给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1
],a[i+2]……a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变一些a[i]的值,改变后,程序还能针对改
变后的a继续回答上面的问题。

输入

第一行有两个正整数n(1≤n≤10000),m(1≤m≤10000)。
分别表示序列的长度和指令的个数。
第二行有n个数,表示a[1],a[2]……a[n],这些数都小于10^9。
接下来的m行描述每条指令
每行的格式是下面两种格式中的一种。 
Q i j k 或者 C i t 
Q i j k (i,j,k是数字,1≤i≤j≤n, 1≤k≤j-i+1)
表示询问指令,询问a[i],a[i+1]……a[j]中第k小的数。
C i t (1≤i≤n,0≤t≤10^9)表示把a[i]改变成为t
m,n≤10000

输出

对于每一次询问,你都需要输出他的答案,每一个输出占单独的一行。

样例输入

5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3

样例输出

3
6
  带修改主席树经典题,树状数组上每个点建一棵主席树,存树状数组上这个点包含的序列中点的信息,修改看成删除和插入,每次操作跳lowbit。
不会带修改主席树的参见->主席树讲解
#include<set>
#include<map>
#include<queue>
#include<cmath>
#include<stack>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
typedef long long ll;
using namespace std;
int n,m;
char ch[2];
int x,y,z;
int cnt;
int tot;
int num;
int ls[8000010];
int rs[8000010];
int sum[8000010];
int root[100010];
int s[100010];
int t[100010];
int a[100010];
int updata(int pre,int l,int r,int k)
{
int rt=++cnt;
if(l==r)
{
sum[rt]=sum[pre]+1;
return rt;
}
ls[rt]=ls[pre];
rs[rt]=rs[pre];
sum[rt]=sum[pre]+1;
int mid=(l+r)>>1;
if(k<=mid)
{
ls[rt]=updata(ls[pre],l,mid,k);
}
else
{
rs[rt]=updata(rs[pre],mid+1,r,k);
}
return rt;
}
int downdata(int pre,int l,int r,int k)
{
int rt=++cnt;
if(l==r)
{
sum[rt]=sum[pre]-1;
return rt;
}
ls[rt]=ls[pre];
rs[rt]=rs[pre];
sum[rt]=sum[pre]-1;
int mid=(l+r)>>1;
if(k<=mid)
{
ls[rt]=downdata(ls[pre],l,mid,k);
}
else
{
rs[rt]=downdata(rs[pre],mid+1,r,k);
}
return rt;
}
void add(int v,int x)
{
for(int i=x;i<=n;i+=i&-i)
{
root[i]=updata(root[i],0,1e9,v);
}
}
void del(int v,int x)
{
for(int i=x;i<=n;i+=i&-i)
{
root[i]=downdata(root[i],0,1e9,v);
}
}
int query(int l,int r,int k)
{
if(l==r)
{
return l;
}
int ans=0;
int res=0;
for(int i=1;i<=num;i++)
{
res+=sum[ls[s[i]]];
}
for(int i=1;i<=tot;i++)
{
ans+=sum[ls[t[i]]];
}
int mid=(l+r)>>1;
if(ans-res>=k)
{
for(int i=1;i<=num;i++)
{
s[i]=ls[s[i]];
}
for(int i=1;i<=tot;i++)
{
t[i]=ls[t[i]];
}
return query(l,mid,k);
}
else
{
for(int i=1;i<=num;i++)
{
s[i]=rs[s[i]];
}
for(int i=1;i<=tot;i++)
{
t[i]=rs[t[i]];
}
return query(mid+1,r,k-(ans-res));
}
}
void ask(int l,int r,int x)
{
num=0;
tot=0;
for(int i=l;i;i-=i&-i)
{
s[++num]=root[i];
}
for(int i=r;i;i-=i&-i)
{
t[++tot]=root[i];
}
printf("%d\n",query(0,1e9,x));
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
add(a[i],i);
}
for(int i=1;i<=m;i++)
{
scanf("%s",ch);
if(ch[0]=='Q')
{
scanf("%d%d%d",&x,&y,&z);
ask(x-1,y,z);
}
else
{
scanf("%d%d",&x,&y);
del(a[x],x);
a[x]=y;
add(a[x],x);
}
}
}

BZOJ1901Zju2112 Dynamic Rankings——树状数组套主席树的更多相关文章

  1. P2617 Dynamic Rankings(树状数组套主席树)

    P2617 Dynamic Rankings 单点修改,区间查询第k大 当然是无脑树套树了~ 树状数组套主席树就好辣 #include<iostream> #include<cstd ...

  2. BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树

    [题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...

  3. ZOJ 2112 Dynamic Rankings(树状数组套主席树 可修改区间第k小)题解

    题意:求区间第k小,节点可修改 思路:如果直接用静态第k小去做,显然我更改一个节点后,后面的树都要改,这个复杂度太高.那么我们想到树状数组思路,树状数组是求前缀和,那么我们可以用树状数组套主席树,求出 ...

  4. LUOGU P2617 Dynamic Rankings(树状数组套主席树)

    传送门 解题思路 动态区间第\(k\)大,树状数组套主席树模板.树状数组的每个位置的意思的是每棵主席树的根,维护的是一个前缀和.然后询问的时候\(log\)个点一起做前缀和,一起移动.时空复杂度\(O ...

  5. BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树

    [题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...

  6. BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树

    BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排 ...

  7. [COGS257]动态排名系统 树状数组套主席树

    257. 动态排名系统 时间限制:5 s   内存限制:512 MB [问题描述]给定一个长度为N的已知序列A[i](1<=i<=N),要求维护这个序列,能够支持以下两种操作:1.查询A[ ...

  8. BZOJ 2141 排队(树状数组套主席树)

    解法很多的题,可以块套树状数组,可以线段树套平衡树.我用的是树状数组套主席树. 题意:给出一段数列,m次操作,每次操作是交换两个位置的数,求每次操作后的逆序对数.(n,m<=2e4). 对于没有 ...

  9. 洛谷P3759 [TJOI2017]不勤劳的图书管理员 【树状数组套主席树】

    题目链接 洛谷P3759 题解 树状数组套主席树板题 #include<algorithm> #include<iostream> #include<cstring> ...

  10. Codeforces Round #404 (Div. 2) E. Anton and Permutation(树状数组套主席树 求出指定数的排名)

    E. Anton and Permutation time limit per test 4 seconds memory limit per test 512 megabytes input sta ...

随机推荐

  1. 【ZOJ 3200】Police and Thief

    ZOJ 3200 首先我写了个高斯消元,但是消出来了一些奇怪的东西,我就放弃了... 然后只好考虑dp:\(dp[i][j][k]\)表示走到了第i步,到了\((j,k)\)这个节点的概率. 那么答案 ...

  2. Luogu P2661 信息传递

    传送门 一眼就能看出来是个并查集 但是并不会写... 看了一下题解说是并查集求最小环qwq 所以,每次加入第i个小同学,判断如果他要告诉的小同学k最后会告诉他(也就是转回来了), 就说明出现了一个环, ...

  3. RabbitMq、ActiveMq、ZeroMq、kafka之间的比较

    MQ框架非常之多,比较流行的有RabbitMq.ActiveMq.ZeroMq.kafka.这几种MQ到底应该选择哪个?要根据自己项目的业务场景和需求.下面我列出这些MQ之间的对比数据和资料. 第一部 ...

  4. 使用第三方库(Senparc)完成小程序支付 - z

    https://www.cnblogs.com/zmaiwxl/p/8931585.html

  5. Luogu P1896 [SCOI2005]互不侵犯

    一道超级简单的状压DP题所以说状压是个好东西 看数据范围,同时我们发现一个格子要么放国王or不放,因此可以用二进制数来表示某一行的国王放置信息 于是我们马上想到用\(f_{i,j}\)表示放了前\(i ...

  6. linux的convert图片处理工具

    得到一个图片的尺寸, identify test.png 结果为: test.png PNG 178x15 178x15+0+0 16-bit PseudoClass 65536c 2.28kb 使用 ...

  7. .net core实践系列之短信服务-Sikiro.SMS.Api服务的实现

    前言 上篇<.net core实践系列之短信服务-架构设计>介绍了我对短信服务的架构设计,同时针对场景解析了我的设计理念.本篇继续讲解Api服务的实现过程. 源码地址:https://gi ...

  8. webpack教程(五)——图片的加载

    首先安装的依赖 npm install file-loader --save-devnpm install image-webpack-loader --save-devnpm install url ...

  9. 如何设置本机电脑的固定IP地址?

    最近使用Loadrunner需要用到IP欺骗,但是我打开设置IP欺骗却提示我:IP向导不支持启用DHCP的网卡.您的卡启用了DHCP或者配置了无效设置.请与系统管理员联系. 我就方了,于是百度了一下, ...

  10. 安装Visual Studio2013

    安装Visual Studio2013现在官网下载在选择安装的可选功能这里,大家可以根据自己需要勾选,也可以默认全选.这里有个小功能,把鼠标放在文字上,会弹出各个功能的详细描述.选择四个常用的功能,另 ...