P2617 Dynamic Rankings(动态区间第k小)

Posted issue是fw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2617 Dynamic Rankings(动态区间第k小)相关的知识,希望对你有一定的参考价值。

LINK

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
#define mid (l+r>>1)
int n,m,li[maxn<<2],top,a[maxn];
struct p
{
	int type,l,r,k;
}q[maxn];

int sum[maxn<<9],ls[maxn<<9],rs[maxn<<9],id;
int rt1[maxn<<9],rt2[maxn<<9],rt[maxn];
inline int lowbit(int x){ return x&(-x); }
void update_sgT(int &rt,int l,int r,int val,int zhi)
{
	if( !rt )	rt = ++id;
	if( l==r ){ sum[rt] += zhi; return; }
	if( val<=mid )	update_sgT( ls[rt],l,mid,val,zhi ); 
	else	update_sgT( rs[rt],mid+1,r,val,zhi );
	sum[rt] = sum[ls[rt]]+sum[rs[rt]]; 
} 
void update_BIT(int x,int val,int zhi)
{
	//把x位置权值线段树上的val位置修改zhi 
	for(;x<=n;x+=lowbit(x) )	update_sgT( rt[x],1,top,val,zhi );
}
void get_root(int l,int r)//获得[l,r]的节点组成前缀树
{
	rt1[0] = rt2[0] = 0;
	for(int i=l-1;i;i-=lowbit(i) )	rt1[++rt1[0]] = rt[i];//返回线段树的根节点 
	for(int i=r;i;i-=lowbit(i) )	rt2[++rt2[0]] = rt[i];	
} 
int ask(int l,int r,int k)
{
//	cout << l << " " << r << endl;
	if( l==r )	return l;
	int x = 0;
	for(int i=1;i<=rt1[0];i++)	x -= sum[ls[rt1[i]]];
	for(int i=1;i<=rt2[0];i++)	x += sum[ls[rt2[i]]];
	if( k<=x )
	{
		for(int i=1;i<=rt1[0];i++)	rt1[i] = ls[rt1[i]];
		for(int i=1;i<=rt2[0];i++)	rt2[i] = ls[rt2[i]];
		return ask(l,mid,k );
	}
	else
	{
		for(int i=1;i<=rt1[0];i++)	rt1[i] = rs[rt1[i]];
		for(int i=1;i<=rt2[0];i++)	rt2[i] = rs[rt2[i]];
		return ask(mid+1,r,k-x );
	}
}
int main()
{
	cin >> n >> m;
	for(int i=1;i<=n;i++)	scanf("%d",&a[i] );
	for(int i=1;i<=n;i++)	li[++top] = a[i]; 
	for(int i=1;i<=m;i++)
	{
		string w; cin >> w;
		if( w=="Q" )
		{
			q[i].type = 0;
			scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].k);
		}
		else
		{
			q[i].type = 1;
			scanf("%d%d",&q[i].l,&q[i].k);	
			li[++top] = q[i].k;
		}
	}
	sort( li+1,li+1+top );
	top = unique(li+1,li+1+top )-li-1;
	for(int i=1;i<=n;i++)
		a[i] = lower_bound( li+1,li+1+top,a[i] )-li;
	for(int i=1;i<=m;i++)
		if( q[i].type )	q[i].k= lower_bound( li+1,li+1+top,q[i].k )-li;
		
	for(int i=1;i<=n;i++)	update_BIT( i,a[i],1 );
	for(int i=1;i<=m;i++)
	{
		if( q[i].type )
		{
			update_BIT( q[i].l,a[q[i].l],-1 );
			a[q[i].l] = q[i].k;
			update_BIT( q[i].l,q[i].k,1 );
		}
		else
		{
			get_root( q[i].l,q[i].r );//取出[1,l-1]和[1,r]的前缀树节点 
			printf("%d\\n",li[ask(1,top,q[i].k)] );
		}
	}
}

以上是关于P2617 Dynamic Rankings(动态区间第k小)的主要内容,如果未能解决你的问题,请参考以下文章

ybt金牌导航4-6-6luogu P2617动态排名 / Dynamic Rankings

P2617 Dynamic Rankings (动态开点权值线段树 + 树状数组)

「Luogu P2617」Dynamic Rankings

[luogu] P2617 Dynamic Rankings

P2617 Dynamic Rankings

P2617 Dynamic Rankings