[COGS 257]动态排名系统 树状数组套主席树

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[COGS 257]动态排名系统 树状数组套主席树相关的知识,希望对你有一定的参考价值。

主席树就是所谓可持久化线段树。目前只会打区间k值操作。

那么带修改的呢?因为主席树目的上也是搞前缀和,所以类比数组操作,套一个树状数组就可以了。

谨以此纪念此类型树套树入门

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define pos(i,a,b) for(int i=(a);i<=(b);i++)
#define N 51000
#include<vector>
#include<algorithm>
int lowbit(int x){
	return x&(-x);
}
int tes;
int n,m,sz,len;
int a[N],root[N];
vector<int> b;
int find(int x){
	return lower_bound(b.begin(),b.end(),x)-b.begin()+1;
}
struct haha{
	int lc,rc,sum;
}tree[N*100];
int ans;
struct xixi{
	int x,y,k;
}cun[N];
int downx[N],downy[N];
void init(){
	memset(tree,0,sizeof(tree));
	memset(cun,0,sizeof(cun));
	b.clear();
	pos(i,0,n+100) a[i]=root[i]=0;
	sz=0;ans=0;len=0;
}
void update(int &rt,int pos,int l,int r,int num){
	if(!rt) rt=++sz;
	if(l==r){
		tree[rt].sum+=num;return;
	}
	int mid=(l+r)>>1;
	if(pos<=mid) update(tree[rt].lc,pos,l,mid,num);
	else update(tree[rt].rc,pos,mid+1,r,num);
	tree[rt].sum=tree[tree[rt].lc].sum+tree[tree[rt].rc].sum;
}
void add(int x,int pos,int num){
	while(x<=n){
		update(root[x],pos,1,len,num);
		x+=lowbit(x);
	}
}
int query(int l,int r,int k){
	if(l==r) return l;
	int mid=(l+r)>>1;
	int sumx(0),sumy(0),t(0);
	pos(i,1,downx[0]) sumx+=tree[tree[downx[i]].lc].sum;
	pos(i,1,downy[0]) sumy+=tree[tree[downy[i]].lc].sum;
	t=sumy-sumx;
	if(t>=k){
		pos(i,1,downx[0]) downx[i]=tree[downx[i]].lc;
		pos(i,1,downy[0]) downy[i]=tree[downy[i]].lc;
		return query(l,mid,k);
	}
	else{
		pos(i,1,downx[0]) downx[i]=tree[downx[i]].rc;
		pos(i,1,downy[0]) downy[i]=tree[downy[i]].rc;
		return query(mid+1,r,k-t);
	}
}
int Query(int x,int y,int k){
	downx[0]=downy[0]=0;
	int tx=x,ty=y;
	while(tx>0){
		downx[++downx[0]]=root[tx];tx-=lowbit(tx);
	}
	while(ty>0){
		downy[++downy[0]]=root[ty];ty-=lowbit(ty);
	}
	return query(1,len,k);
}
int main(){
	scanf("%d",&tes);
	while(tes--){
		scanf("%d%d",&n,&m);
		init();
		pos(i,1,n) scanf("%d",&a[i]),b.push_back(a[i]);
		pos(i,1,m){
			char c;cin>>c;
			int x,y,k;scanf("%d%d",&x,&y);
			cun[i].x=x;cun[i].y=y;
			if(c==‘Q‘){
				scanf("%d",&k);cun[i].k=k;
			}
			else{
				b.push_back(y);
			}
		}
		sort(b.begin(),b.end());
		b.erase(unique(b.begin(),b.end()),b.end());
		len=b.size();
		pos(i,1,n){
			add(i,find(a[i]),1);
		}
		pos(i,1,m){
			int x=cun[i].x,y=cun[i].y,k=cun[i].k;
			if(k){
				ans=Query(x-1,y,k);
				ans=b[ans-1];
				printf("%d\n",ans);
			}
			else{
				add(x,find(a[x]),-1);
				add(x,find(y),1);
				a[x]=y;
			}
		}
	}
	return 0;
}

  

以上是关于[COGS 257]动态排名系统 树状数组套主席树的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 1901Zju 2112 Dynamic Rankings 动态K值 树状数组套主席树模板题

关于树状数组套主席树的一些博客

树套树三题 题解

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

浅谈树状数组套主席树

BZOJ 3110: [Zjoi2013]K大数查询( 树状数组套主席树 )