ZOJ 2112 Dynamic Rankings


参考:

http://blog.csdn.net/acm_cxlove/article/details/8565309

http://www.cnblogs.com/Rlemon/archive/2013/05/24/3096264.html

http://www.cnblogs.com/kuangbin/p/3308118.html

http://seter.is-programmer.com/posts/31907.html


#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#define lowbit(x) (x&(-x))
using namespace std;
const int N = 60005;
const int M = N * 40;//前几次用了30倍   WA了几发
const int MM = 10005;
int n,m,q,tot;
int a[N],t[N];
int T[N],ls[M],rs[M],c[M],use[N],s[N];
struct Question{
	int kind, l, r, k;
}que[MM];
void Init_hash(){
	sort(t+1,t+m+1);
	m = unique(t+1,t+1+m)-t-1;
}
int hash(int x){
	return lower_bound(t+1,t+1+m,x)-t;
}
void build(int l, int r, int &rt){
	rt = tot ++;
	c[rt] = 0;
	if(l != r){
		int mid = (l+r)>>1;
		build(l, mid, ls[rt] );
		build(mid+1, r, rs[rt]);
	}
}
int update(int root, int pos, int val){
	int newroot = tot++, tmp = newroot;
	c[newroot] = c[root] + val;
	int l = 1, r = m;
	while(l < r){
		int mid = (l+r)>>1;
		if(pos <= mid){
			ls[newroot] = tot++;
			rs[newroot] = rs[root];
			newroot = ls[newroot];
			root = ls[root];
			r = mid;
		}
		else {
			rs[newroot] = tot++;
			ls[newroot] = ls[root];
			newroot = rs[newroot];
			root = rs[root];
			l = mid+1;
		}
		c[newroot] = c[root] + val;
	}
	return tmp;
}
void Modify(int x, int pos, int val){
	while(x<=n){
		s[x] = update(s[x],pos,val);
		x += lowbit(x);
	}
}
int sum(int x){
	int ret = 0;
	while(x>0){
		ret += c[ls[use[x]]];
		x -= lowbit(x);
	}
	return ret;
}
int query(int left, int right, int k){
	int left_root = T[left-1], right_root = T[right];
	int l = 1, r = m;
	for(int i = left-1; i; i -= lowbit(i))use[i] = s[i];
	for(int i = right;  i; i -= lowbit(i))use[i] = s[i];
	while(l < r){
		int mid = (l+r)>>1;
		int cot = sum(right) - sum(left-1) + c[ls[right_root]] - c[ls[left_root]];
		if(cot >= k){
			r = mid;
			left_root = ls[left_root];
			right_root = ls[right_root];
			for(int i = left-1; i; i -= lowbit(i))use[i] = ls[use[i]];
			for(int i = right;  i; i -= lowbit(i))use[i] = ls[use[i]];
		}
		else {
			l = mid+1;
			k -= cot;
			left_root = rs[left_root];
			right_root = rs[right_root];
			for(int i = left-1; i; i -= lowbit(i))use[i] = rs[use[i]];
			for(int i = right;  i; i -= lowbit(i))use[i] = rs[use[i]];
		}
	}
	return l;
}
int main(){
	char str[5];
	int l,r,k,ks;
	//freopen("in.txt","r",stdin);
	scanf("%d",&ks);
	while(ks--){
		scanf("%d%d",&n, &q);
		tot = m = 0;
		for(int i = 1; i <= n; i++ ){
			scanf("%d", a+i);
			t[++m] = a[i];
		}
		for(int i = 0; i < q; i++){
			scanf("%s",str);
			if(str[0] == 'Q'){
				scanf("%d%d%d", &l, &r, &k);
				que[i] = Question{0, l, r, k};
			}
			else {
				scanf("%d%d", &l, &k);
				que[i] = Question{1, l, 0, k};
				t[++m] = k;
			}
		}
		Init_hash();
		build(1,m,T[0]);
		for(int i = 1; i <= n; i++){
			T[i] = update(T[i-1], hash(a[i]), 1);
			s[i] = T[0];
		}
		for(int i = 0; i < q; i++){
			if(que[i].kind == 0){
				printf("%d\n",t[query(que[i].l,que[i].r,que[i].k)]);
			}
			else {
				Modify(que[i].l,hash(a[que[i].l]),-1);
				Modify(que[i].l,hash(que[i].k),1);
				a[que[i].l] = que[i].k;
			}
		}
	}
	return 0;
}


你可能感兴趣的:(ZOJ,树状数组,主席树,树套树)