动态区间第K大(树状数组+主席树)


很早以前做静态第K大的时候听到要用树套树就过于害怕逃走了,现在用分块暴力过了之后又想用树套树A一遍,于是就写了一下
starkmal的线段树+Splay常数卡出翔惹


  • 其实如果用主席树写了静态第k大就立即做这道题的话应该立即想到用主席树搞废话
  • 但是立即就能发现的问题就是定点修改之后我们需要将其后面的所有版本都修改一遍,不优秀,所以用树状数组维护版本信息。(仔细想想,这正好是树状数组的特性,记住修改节点含义)
  • 这里 1 <= n, m, A k A_k Ak <= 50000, 玄学oj上10个点时间接近3800ms
  • 没有离散化
#prag\
ma GCC optimize("O3") 
#include 
#include 
#include 
#include 
#include 
#include 
#define mid (l+r>>1)
#define mid_1 ((l+r>>1)+1)
#define R(XXX) scanf("%d",&XXX)
#define DR(XXX,YYY) scanf("%d%d",&XXX,&YYY)
#define TR(XXX,YYY,ZZZ) scanf("%d%d%d",&XXX,&YYY,&ZZZ)
#define P(XXX) printf("%d\n",XXX)
#define lowbit(i) (i&-i)
using namespace std;
const int N = 50005;

int a[N], n, m, tot, Max, _0, _1, _2;

char cmd;
int ver[N], c[26000010], v, d;
int xx[N], yy[N], ls[26000010], rs[26000010];


void update( int &p, int l, int r ){
	if( ! p ) p = ++ tot; c[p] += d;
	if( l == r ) return;
	if( v <= mid ) update( ls[p], l, mid );
	else update( rs[p], mid_1, r );
}

void modify(){
	DR( _0, _1 );
	d = -1; v = a[_0];
	for( int i = _0; i <= n; i += lowbit(i) )
		update( ver[i], 0, N );
	d = 1; v = _1;
	for( int i = _0; i <= n; i += lowbit(i) )
		update( ver[i], 0, N );
	a[_0] = _1;
}


int query(){
	TR( _0, _1, _2 ); _0 --;
	int x = 0, y = 0, tmp;
	for( int i = _1; i; i ^= lowbit( i ) ) xx[x++] = ver[i];
	for( int i = _0; i; i ^= lowbit( i ) ) yy[y++] = ver[i];
	int l = 0, r = N;
	while( l < r ){
		tmp = 0;
		for( int i = 0; i < x; i ++ ) tmp += c[ls[xx[i]]];
		for( int i = 0; i < y; i ++ ) tmp -= c[ls[yy[i]]];
		if( _2 <= tmp ){
			for( int i = 0; i < x; i ++ ) xx[i] = ls[xx[i]];
			for( int i = 0; i < y; i ++ ) yy[i] = ls[yy[i]];
			r = mid;
		}
		else{
			for( int i = 0; i < x; i ++ ) xx[i] = rs[xx[i]];
			for( int i = 0; i < y; i ++ ) yy[i] = rs[yy[i]];
			_2 -= tmp; l = mid_1;
		}
	}
	return l;
}


int main()
{
//	freopen("tt.in","r",stdin);
	DR( n, m );
	d = 1;
	for( int i = 1; i <= n; i ++ ){ R(a[i]); v = a[i];
		for( int j = i; j <= n; j += lowbit(j) )
			update( ver[j], 0, N ); }
	while( m -- ){
		cin >> cmd;
		if( cmd == 'C' ) modify();
		else P( query() );
	}
	return 0;
}

你可能感兴趣的:(主席树,树状数组,数据结构)