题意

\(n\) 个数,\(m\) 个操作,每次操作修改某个数,或者询问某个区间的第 \(K\) 小值。

\(1 \leq n \leq 50000\)

\(1 \leq m \leq 10000\)

思路

动态区间第 \(K\) 小的模板题。回到主席树的职能,它维护了一排前缀线段树,假如我们要快速求一段区间的总和,显然优先考虑前缀和;然而如果带上修改,就要考虑树状数组了。这里也相同,我们只需用树状数组套主席树即可,\(x\) 号主席树维护的不再是 \([1,x]\) 的信息,而是 \([x-\text{lowbit(x)}+1,x]\) 的信息。

修改时,像树状数组的修改一样不断加 \(\text{lowbit}\) ,修改 \(\log\) 棵主席树。

查询时,像树状数组一样不断减 \(\text{lowbit}\) ,查询 \(2\log\) 棵主席树。这里可以传入两个 \(\text{vector}\) ,一个加、一个减,然后就可以轻松求出区间第 \(K\) 值了。

总复杂度 \((n+m)\log^2n\) ,然而过不了。

这道题比较卡常,初始的序列应该再用一棵静态主席树解决,动态主席树只存修改的信息,查询时额外加入静态主席树上要加的位置和要减的位置即可。

总复杂度 \(m\log^2n\) ,现在可以过了。

代码

#include<bits/stdc++.h>
#define FOR(i,x,y) for(int i=(x),i##END=(y);i<=i##END;++i)
#define DOR(i,x,y) for(int i=(x),i##END=(y);i>=i##END;--i)
typedef long long LL;
using namespace std;
const int N=5e4+5;
const int M=1e4+5;
const int NN=2e6+5;
struct ChairmanTree
{
int lson[NN],rson[NN],cnt[NN];
int rt[N+N],tot;
int &operator [](const int x){return rt[x];}
void build()
{
memset(rt,0,sizeof(rt));
cnt[tot=0]=0,lson[0]=rson[0]=0;
}
void create(int &k){cnt[++tot]=cnt[k],lson[tot]=lson[k],rson[tot]=rson[k],k=tot;}
void update(int &k,int x,int val,int l,int r)
{
create(k);
if(l==r)
{
cnt[k]+=val;
return;
}
int mid=(l+r)>>1;
if(x<=mid)update(lson[k],x,val,l,mid);
else update(rson[k],x,val,mid+1,r);
cnt[k]=cnt[lson[k]]+cnt[rson[k]];
}
int query(vector<int>&A,vector<int>&B,int K,int l,int r)
{
if(l==r)return l;
int mid=(l+r)>>1,Cnt=0;
FOR(i,0,(int)A.size()-1)Cnt+=cnt[lson[A[i]]];
FOR(i,0,(int)B.size()-1)Cnt-=cnt[lson[B[i]]];
if(Cnt>=K)
{
FOR(i,0,(int)A.size()-1)A[i]=lson[A[i]];
FOR(i,0,(int)B.size()-1)B[i]=lson[B[i]];
return query(A,B,K,l,mid);
}
else
{
FOR(i,0,(int)A.size()-1)A[i]=rson[A[i]];
FOR(i,0,(int)B.size()-1)B[i]=rson[B[i]];
return query(A,B,K-Cnt,mid+1,r);
}
}
}CT;
int a[N],L[M],R[M],K[M],disc[N+M];
int n,m,tot;
#define lowbit(x) ((x)&-(x))
void update(int k,int val)
{
int _val=a[k];
a[k]=val;
for(;k<=n;k+=lowbit(k))
{
CT.update(CT[k],_val,-1,1,tot);
CT.update(CT[k],val,1,1,tot);
}
}
int query(int l,int r,int k)
{
vector<int>A,B;
A.clear(),B.clear();
A.push_back(CT[N+r]),B.push_back(CT[N+l-1]);
for(;r>0;r^=lowbit(r))A.push_back(CT[r]);
for(l--;l>0;l^=lowbit(l))B.push_back(CT[l]); return CT.query(A,B,k,1,tot);
}
#undef lowbit int main()
{
int T;
scanf("%d",&T);
while(T--)
{
CT.build();
tot=0;
scanf("%d%d",&n,&m);
FOR(i,1,n)scanf("%d",&a[i]),disc[++tot]=a[i];
FOR(i,1,m)
{
char str[5];
scanf("%s",str);
if(str[0]=='Q')scanf("%d%d%d",&L[i],&R[i],&K[i]);
else scanf("%d%d",&L[i],&R[i]),K[i]=-1,disc[++tot]=R[i];
} sort(disc+1,disc+1+tot);
tot=unique(disc+1,disc+1+tot)-disc-1;
FOR(i,1,n)a[i]=lower_bound(disc+1,disc+1+tot,a[i])-disc;
FOR(i,1,m)if(K[i]==-1)R[i]=lower_bound(disc+1,disc+1+tot,R[i])-disc; FOR(i,1,n)CT.update(CT[N+i]=CT[N+i-1],a[i],1,1,tot);
FOR(i,1,m)
{
if(K[i]!=-1)printf("%d\n",disc[query(L[i],R[i],K[i])]);
else update(L[i],R[i]);
}
}
return 0;
}

ZOJ 2112 Dynamic Rankings(树状数组+主席树)的更多相关文章

  1. ZOJ - 2112 Dynamic Rankings(BIT套主席树)

    纠结了好久的一道题,以前是用线段树套平衡树二分做的,感觉时间复杂度和分块差不多了... 终于用BIT套函数式线段树了过了,120ms就是快,此题主要是卡内存. 假设离散后有ns个不同的值,递归层数是l ...

  2. BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树

    BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树 题意: 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i, ...

  3. zoj2112 树状数组+主席树 区间动第k大

    Dynamic Rankings Time Limit: 10000MS   Memory Limit: 32768KB   64bit IO Format: %lld & %llu Subm ...

  4. 【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树

    题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...

  5. 【bzoj3744】Gty的妹子序列 分块+树状数组+主席树

    题目描述 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成 ...

  6. BZOJ_2120_数颜色_Set+树状数组+主席树

    BZOJ_2120_数颜色_Set+树状数组+主席树 Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L ...

  7. P1972 [SDOI2009]HH的项链[离线+树状数组/主席树/分块/模拟]

    题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集新的贝壳,因此,他的项链 ...

  8. ZOJ 2112 Dynamic Rankings(树状数组+主席树)

    The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with t ...

  9. [luogu2617][bzoj1901][Zju2112]Dynamic Rankings【树套树+树状数组+主席树】

    题目网址 [传送门] 题目大意 请你设计一个数据结构,支持单点修改,区间查询排名k. 感想(以下省略脏话inf个字) 真的强力吹爆洛谷数据,一般的树套树还给我T了一般的点,加强的待修主席树还给我卡了几 ...

随机推荐

  1. Eureka (数学组合 + 斜率)

    由于斜率的储存精度不够,所以使用最简分数表示记录. 合并同一个位置上的点,然后统计个数,利用公式先求出至少包含2个点的数量. 然后再是求某位之上的点与某一斜率的个数,那就是每边至少一个点的个数相乘. ...

  2. Spring cglib 初始化 ExceptionInInitializerError,new Enhancer() 异常

    解决办法:更换 spring-cglib-repack-*.*.jar 包 java.lang.ExceptionInInitializerError at org.springframework.a ...

  3. 20165305 实验二:Java面向对象程序设计

    2-1 参考 http://www.cnblogs.com/rocedu/p/6371315.html#SECUNITTEST 参考http://www.cnblogs.com/rocedu/p/67 ...

  4. Python数据类型深入学习之数字

    一. 数字常量 1. 下面来看看Python的数字常量中都要哪些类型: 数字 常量 129,-89,0 一般整数 9999848499999L,4594646469l 长整型数(无限大小) 1.232 ...

  5. <转>jmeter(三)SOAP/XML-RPC Request

    本博客转载自:http://www.cnblogs.com/imyalost/category/846346.html 个人感觉不错,对jmeter讲解非常详细,担心以后找不到了,所以转发出来,留着慢 ...

  6. MySQL性能测试工具sysbench的安装和使用

    sysbench是一个开源的.模块化的.跨平台的多线程性能测试工具,可以用来进行CPU.内存.磁盘I/O.线程.数据库的性能测试.目前支持的数据库有MySQL.Oracle和PostgreSQL.当前 ...

  7. game to refactor for refactor

    first step, only aim to work. it works, but i have not seen the necessaty to use class yet. my quest ...

  8. Golang操作Redis

    在系统环境下实现redis操作必须做好以下准备 一.当前系统必须下载安装redis 二.配置好GOPATH环境变量,并下载GO的redis驱动包 当做好以上准备工作时,紧接着如下 看以下要使用的驱动包 ...

  9. oracle 12c多租户下的日常操作变化

    Oracle 12c创建用户时出现“ORA-65096: invalid common user or role name”的错误 在oracle中,引入了多租户概念,以前是一个instance对应一 ...

  10. 【题解】Luogu P4979 矿洞:坍塌

    原题传送门:P4979 矿洞:坍塌 这是某场膜你赛的题,最后我一百零几分rank三十几滚粗 这是我唯一ac的一题 这题比较简单qaq 前置芝士:珂朵莉树 窝博客里对珂朵莉树的介绍 没什么好说的自己看看 ...