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\n",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;
		}
	}
}
posted @ 2020-06-17 07:56  白木偶君  阅读(123)  评论(0编辑  收藏  举报