首页 > 其他 > 详细

Dynamic Rankings(数据结构)

时间:2020-08-07 22:25:35      阅读:86      评论:0      收藏:0      [点我收藏+]

description

给定一个长度为\(n\)的序列\(\{ a \}\),需支持两种操作:查询区间\([L,R]\)中第\(k\)小的数;将\(a_{x}\)改为\(y\).

solution

此题需支持动态区间kth查询,不难想到用主席树进行维护,然后至于单点修改操作,可以用树状数组维护前缀和.

code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#define R register
#define next kdjadskfj
#define debug puts("mlg")
#define mod 10000000007
#define Mod(x) ((x%mod+mod)%mod)
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
inline ll read();
inline void write(ll x);
inline void writeln(ll x);
inline void writesp(ll x);
inline ll lowbit(ll x){return x&-x;}
const ll maxn=1e6+5;
struct node{
	ll op,l,r,k,x,y;
}q[maxn];
ll n,m;
ll a[maxn];
ll lsh[maxn<<1],h;
ll rt[maxn<<1],cnt;
struct seg{
	ll ls,rs,dat;
}t[maxn<<4];
ll temp[2][maxn],tot[2];

inline void update(ll &p,ll l,ll r,ll k,ll val){
	if(!p) p=++cnt;
	t[p].dat+=val;
	if(l==r) return;
	ll mid=l+r>>1;
	if(k<=mid) update(t[p].ls,l,mid,k,val);
	else update(t[p].rs,mid+1,r,k,val);
}

inline void True_update(ll pos,ll val){
	for(R ll i=pos;i<=n;i+=lowbit(i)) update(rt[i],1,h,a[pos],val);
}

inline ll query(ll l,ll r,ll k){
	if(l==r) return l;
	ll mid=l+r>>1,sum=0;
	for(R ll i=1;i<=tot[0];i++) sum+=t[t[temp[0][i]].ls].dat;
	for(R ll i=1;i<=tot[1];i++) sum-=t[t[temp[1][i]].ls].dat;
	if(k<=sum){
		for(R ll i=1;i<=tot[0];i++) temp[0][i]=t[temp[0][i]].ls;
		for(R ll i=1;i<=tot[1];i++) temp[1][i]=t[temp[1][i]].ls;
		return query(l,mid,k);
	}
	else{
		for(R ll i=1;i<=tot[0];i++) temp[0][i]=t[temp[0][i]].rs;
		for(R ll i=1;i<=tot[1];i++) temp[1][i]=t[temp[1][i]].rs;
		return query(mid+1,r,k-sum);
	}
}

inline ll True_query(ll l,ll r,ll k){
	tot[0]=tot[1]=0;
	for(R ll i=r;i;i-=lowbit(i)) temp[0][++tot[0]]=rt[i];
	for(R ll i=l-1;i;i-=lowbit(i)) temp[1][++tot[1]]=rt[i];
	return query(1,h,k);
}
int main(){
	n=read();m=read();
	for(R ll i=1;i<=n;i++) a[i]=lsh[++h]=read();	
	for(R ll i=1;i<=m;i++){
		char wn=getchar();
		while(wn!=‘Q‘&&wn!=‘C‘) wn=getchar();
		if(wn==‘Q‘){
			q[i].op=1;q[i].l=read();q[i].r=read();q[i].k=read();
		}
		else{
			q[i].op=2;q[i].x=read();lsh[++h]=q[i].y=read();
		}
	}
	sort(lsh+1,lsh+h+1);
	h=unique(lsh+1,lsh+h+1)-lsh-1;
	for(R ll i=1;i<=n;i++) a[i]=lower_bound(lsh+1,lsh+h+1,a[i])-lsh;
	for(R ll i=1;i<=n;i++) True_update(i,1);
	for(R ll i=1;i<=m;i++){
		if(q[i].op==1){
			writeln(lsh[True_query(q[i].l,q[i].r,q[i].k)]);
		}
		else{
			True_update(q[i].x,-1);
			a[q[i].x]=lower_bound(lsh+1,lsh+h+1,q[i].y)-lsh;
			True_update(q[i].x,1);
		}
	}
}
inline ll read(){ll x=0,t=1;char ch=getchar();while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘) t=-1;ch=getchar();}while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}return x*t;}
inline void write(ll x){if(x<0){putchar(‘-‘);x=-x;}if(x<=9){putchar(x+‘0‘);return;}write(x/10);putchar(x%10+‘0‘);}
inline void writesp(ll x){write(x);putchar(‘ ‘);}
inline void writeln(ll x){write(x);putchar(‘\n‘);}

Dynamic Rankings(数据结构)

原文:https://www.cnblogs.com/ylwtsq/p/13455285.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!