zoukankan      html  css  js  c++  java
  • 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('
    ');}
    
  • 相关阅读:
    黑芝麻智能技术
    景嘉微GPU与显卡
    电子表格文档控件DevExpress Office File API v21.1
    WPF界面控件Telerik UI for WPF初级入门教程
    WPF应用程序的交互界面还有这些样式,赶紧Get
    手把手教你创建一个Windows风格的应用程序界面(Part 1)
    Web应用的数据管理教程
    Visual Studio插件CodeRush正式发布v21.1.5,免费高速下载
    Mysqldump 备份说明及数据库备份脚本分享-运维笔记
    某国有银行的超融合技术选型和应用实践
  • 原文地址:https://www.cnblogs.com/ylwtsq/p/13455285.html
Copyright © 2011-2022 走看看