pku 2104 归并排序树

#include <iostream>
using namespace std;

const long MAXN = 100010;
long arr[20][MAXN];
long ori[MAXN];
long n, m;
bool flag;

inline long MIN(long a, long b)
{
	return a < b ? a : b;
}

inline long MAX(long a, long b)
{
	return a > b ? a : b;
}

void merge_tree(long root, long a, long b, long depth)
{
	if (a == b)
	{
		arr[depth][a] = ori[a];
		return;
	}
	else
	{
		long mid = (a + b) / 2;
		merge_tree(root<<1, a, mid, depth+1);
		merge_tree((root<<1)+1, mid+1, b, depth+1);
		long i, j, k;
		for (i=a, j=mid+1, k=a; i<=mid&&j<=b;)
		{
			if (arr[depth+1][i] < arr[depth+1][j])
			{
				arr[depth][k++] = arr[depth+1][i++];
			}
			else
			{
				arr[depth][k++] = arr[depth+1][j++];
			}
		}
		while (i <= mid)
		{
			arr[depth][k++] = arr[depth+1][i++];
		}
		while (j <= b)
		{
			arr[depth][k++] = arr[depth+1][j++];
		}
	}
}

long query(long root, long a, long b, long l, long r, long depth, long num)
{
	if (a == l && b == r)
	{
		long low = a, high = b, mid;
		while (low <= high)
		{
			mid = (low + high) / 2;
			if (arr[depth][mid] < num)
			{
				low = mid + 1;
			}
			else if (arr[depth][mid] > num)
			{
				high = mid - 1;
			}
			else 
			{
				flag = true;
				return mid-a+1;
			}
		}
		return high-a+1;
	}
	else
	{
		long ans = 0, mid = (a+b)/2;
		if (l <= mid)
		{
			ans += query(root<<1, a, mid, l, MIN(r,mid), depth+1, num);
		}
		if (r > mid)
		{
			ans += query((root<<1)+1, mid+1, b, MAX(l, mid+1), r, depth+1, num);
		}
		return ans;
	}
}
int main()
{
	while (scanf("%ld %ld", &n, &m) != EOF)
	{
		long i;
		for (i = 1; i <= n; ++i)
		{
			scanf("%ld", &ori[i]);
		}
		merge_tree(1, 1, n, 0);
		for (i = 1; i <= m; ++i)
		{
			long k, l, r;
			scanf("%ld %ld %ld", &l, &r, &k);
			
			long low=-1000000000, high=1000000000, mid;
			while (low <= high)
			{
				mid = (low+high)/2;
				flag = false;
				long res = query(1, 1, n, l, r, 0, mid);
				if (res == k && flag)
				{
					printf("%ld\n", mid);
					break;
				}
				else if (res < k)
				{
					low = mid + 1;
				}
				else if (res > k || (res == k && !flag))
				{
					high = mid - 1;
				}
			}
		}
	}
	return 0;
}

你可能感兴趣的:(pku 2104 归并排序树)