UVa 501 - Black Box

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mobius_strip/article/details/82779120

题目

有一个数据库,有两种操作:ADD(x),将数字x插入到数据库中;GET返回第i个元素,i初始为1,每次使用GET先将i增加1再查询。

分析

数据结构,首先利用离散化将数据映射到1~M,然后使用线段树进行存储和查找,记录每个区间的数据个数方便查询。

说明

注意数据中有M为0的情况,这时使用排序会RE。又是好久没刷题了(⊙o⊙)…。

#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <cstdio>

using namespace std; 
 
//segment_tree__begin
typedef struct tnode
{
	tnode* Lchild;
	tnode* Rchild;
	int    Lvalue;
	int    Rvalue;
	int    Size;
	int    Value;
}tnode;
tnode Node[60006];

class segment_tree 
{
private:
	tnode* Root;
	int    Count;
	tnode* madetree(int a, int b) {
		tnode* np = &Node[Count ++];
		np->Lvalue = a;
		np->Rvalue = b;
		np->Lchild = NULL;
		np->Rchild = NULL;
		np->Size   = 0;
		np->Value  = 0;
		if (a < b) {
			np->Lchild = madetree(a, (a+b)/2);
			np->Rchild = madetree((a+b)/2+1, b);
		}
		return np;
	}
public:
	segment_tree(int a, int b) {
		Count = 0;
		Root = madetree(a, b);
	}
	void Insert(int im, int re) {
		Insert(Root, im, re);
	}
	int Query(int index) {
		return Query(Root, index);
	}
private:
	void Insert(tnode* r, int im, int re) {
		if (im == r->Lvalue && im == r->Rvalue) {
			r->Value = re;
			r->Size  = 1;
		} else {
			r->Size ++;
			if (r->Lchild && r->Lchild->Rvalue >= im) { 
				Insert(r->Lchild, im, re);
			} else if (r->Rchild) {
				Insert(r->Rchild, im, re);
			}
		}
	}
	int Query(tnode* r, int index) {
		if (r->Lvalue == r->Rvalue && index == 1 && r->Size == 1) {
			return r->Value;
		} else {
			if (r->Lchild && r->Lchild->Size >= index) {
				return Query(r->Lchild, index);
			} else if (r->Rchild) {
				if (r->Lchild) {
					return Query(r->Rchild, index - r->Lchild->Size);
				} else if (r->Rchild->Size >= index) {
					return Query(r->Rchild, index);
				}
			}
		}
	}
};
//segment_tree__end

int A[30003];
int u[30003];
int I[30003];
int S[30003];

bool my_cmp(int a, int b)
{
	return A[a] < A[b]; 
}

int main()
{
	int K, M, N;
	while (~scanf("%d", &K))
	while (K --) {
		scanf("%d%d", &M, &N);
		for (int i = 1; i <= M; ++ i) {
			scanf("%d", &A[i]);	
			I[i] = i;
		}
		for (int i = 1; i <= N; ++ i) {
			scanf("%d", &u[i]);
		}
		
		if (M) { // avoid M is 0
			sort(I+1, I+M+1, my_cmp);
		}
		for (int i = 1; i <= M; ++ i) {
			S[I[i]] = i;
		}
		segment_tree ST(1, M);
		
		int index = 0, u_count = 1;
		for (int i = 1; i <= M; ++ i) {
			ST.Insert(S[i], A[i]);
			while (u_count <= N && u[u_count] == i) {
				// ST.output();
				index ++;
				printf("%d\n", ST.Query(index));
				u_count ++;
			}
		}
		
		if (K) {
			puts("");
		}
	}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/mobius_strip/article/details/82779120