• luogu P2617 Dynamic Rankings |树套树


    题目描述

    给定一个含有 (n) 个数的序列 (a_1,a_2 dots a_n),需要支持两种操作:

    Q l r k 表示查询下标在区间 ([l,r]) 中的第 (k) 小的数
    C x y 表示将 (a_x)​ 改为 (y)

    输入格式

    第一行两个正整数 (n,m),表示序列长度与操作个数。
    第二行 (n) 个整数,表示 (a_1,a_2 dots a_n)
    接下来 (m) 行,每行表示一个操作,都为上述两种中的一个。

    输出格式

    对于每一次询问,输出一行一个整数表示答案。


    离散化莫名出锅


    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int N=2e5+5;
    inline int read(){
    	int x=0; char c=getchar();
    	while(c<'0'||c>'9')c=getchar();
    	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48); c=getchar();}
    	return x;
    }
    #define mid ((l+r)>>1)
    int a[N],n,m,len;
    int T[N*600],ls[N*600],rs[N*600],val[N*600],cnt;
    void update(int &p,int l,int r,int pos,int d){
    	if(!p)p=++cnt;
    	if(l==r){ val[p]+=d; return; }
    	if(pos<=mid)update(ls[p],l,mid,pos,d);
    	else update(rs[p],mid+1,r,pos,d);
    	val[p]=val[ls[p]]+val[rs[p]];
    }
    void add(int x,int y){
    	for(;x<=n;x+=x&(-x))update(T[x],1,len,y,1);
    }
    void del(int x,int y){
    	for(;x<=n;x+=x&(-x))update(T[x],1,len,y,-1);
    }
    struct QU{
    	int opt,l,r,k;
    }e[N];
    int b[N],top;
    struct node{
    	vector<int>A,B;
    	inline int sum(){
    		int x=0;
    		for(int i=0;i<A.size();i++)x+=val[ls[A[i]]];
    		for(int i=0;i<B.size();i++)x-=val[ls[B[i]]];
    		return x;
    	}
    	inline void changel(){
    		for(int i=0;i<A.size();i++)A[i]=ls[A[i]];
    		for(int i=0;i<B.size();i++)B[i]=ls[B[i]];
    	}
    	inline void changer(){
    		for(int i=0;i<A.size();i++)A[i]=rs[A[i]];
    		for(int i=0;i<B.size();i++)B[i]=rs[B[i]];
    	}	
    };
    vector<int> sum(int x){
    	vector<int>Q; Q.clear();
    	for(;x;x-=x&(-x))Q.push_back(T[x]);
    	return Q;
    }
    int query(node p,int l,int r,int k){
    	if(l==r)return l;
    	int x=p.sum();
    	if(k<=x){
    		p.changel();
    		return query(p,l,mid,k);
    	}else{
    		p.changer();
    		return query(p,mid+1,r,k-x);
    	}
    }
    signed main(){
    	n=read(),m=read();
    	for(int i=1;i<=n;i++)b[i]=a[i]=read(); top=n;
    	char ch[4];
    	for(int i=1;i<=m;i++){
    		scanf("%s",ch);
    		if(ch[0]=='Q')e[i].l=read(),e[i].r=read(),e[i].k=read(),e[i].opt=1;
    		else e[i].l=read(),e[i].r=read(),b[++top]=e[i].r;
    	}
    	sort(b+1,b+1+top);
    	len=top;
    	for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+len+1,a[i])-b;
    	for(int i=1;i<=n;i++)add(i,a[i]);
    	for(int i=1;i<=m;i++){
    		int opt=e[i].opt,l=e[i].l,r=e[i].r,k=e[i].k;
    		if(opt==1){
    			node t=(node){sum(r),sum(l-1)};
    			printf("%d
    ",b[query(t,1,len,k)]);
    		}else{
    			r=lower_bound(b+1,b+1+top,r)-b;
    			del(l,a[l]);
    			add(l,r);
    			a[l]=r;
    		}
    	}
    }
    
  • 相关阅读:
    C# 连接 Oracle 的几种方式
    Mac电脑卸载软件后删除残余图标
    文件监视器数量达到系统限制
    Android实现伸缩弹力分布菜单效果
    XMPP协议实现原理介绍
    Android开发之日历控件实现
    OpenGL开发之旅基础知识介绍
    Android in Mono开发初体验之DataBase
    JAVA实现随机无重复数字功能
    Android实现宫格图片连续滑动效果
  • 原文地址:https://www.cnblogs.com/naruto-mzx/p/13150327.html
Copyright © 2020-2023  润新知