• Dynamic Rankings(数据结构)


    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('
    ');}
    
  • 相关阅读:
    python异常触发及自定义异常类
    python for i in range(x)应用的问题
    季羡林 暮年沉思录
    再谈python的list类型参数及复制
    Python 列表推导式
    JavaScript:垃圾数据是如何自动回收的?
    JavaScript:this的用法
    JavaScript:浅谈闭包及其回收原则
    ES6:async / await ---使用同步方式写异步代码
    五大主流浏览器与四大浏览器内核
  • 原文地址:https://www.cnblogs.com/ylwtsq/p/13455285.html
Copyright © 2020-2023  润新知