您的位置:首页 > 其它

TOJ 4325 RMQ with Shifts / 线段树单点更新

2013-10-29 11:26 483 查看

RMQ with Shifts

时间限制(普通/Java):1000MS/3000MS 运行内存限制:65536KByte



描述

In the traditional RMQ (Range Minimum Query) problem, we have a static array A. Then for each query (L, R) (L<=R), we report the minimum value among A[L], A[L+1], …, A[R]. Note that the indices start from 1, i.e. the left-most
element is A[1].

In this problem, the array A is no longer static: we need to support another operation shift(i1, i2, i3, …, ik) (i1<i2<...<ik, k>1): we do a left “circular shift” of A[i1], A[i2], …, A[ik].

For example, if A={6, 2, 4, 8, 5, 1, 4}, then shift(2, 4, 5, 7) yields {6, 8, 4, 5, 4, 1, 2}. After that, shift(1,2) yields {8, 6, 4, 5, 4, 1, 2}.

输入

There will be only one test case, beginning with two integers n, q (1<=n<=100,000, 1<=q<=120,000), the number of integers in array A, and the number of operations. The next line contains n positive integers not greater than 100,000, the initial elements
in array A. Each of the next q lines contains an operation. Each operation is formatted as a string having no more than 30 characters, with no space characters inside. All operations are guaranteed to be valid. Warning: The dataset is large, better to use
faster I/O methods.

输出

For each query, print the minimum value (rather than index) in the requested range.

样例输入

7 5
6 2 4 8 5 1 4
query(3,7)
shift(2,4,5,7)
query(1,4)
shift(1,2)
query(2,2)


样例输出

1
4
6

#include <stdio.h>
#define MAX 100010
int a[MAX * 4];
int pos[MAX];
int min(int x,int y)
{
	return x < y ? x : y;
}
void build(int l,int r,int rt)
{
	if(l == r)
	{
		pos[l] = rt;
		scanf("%d",&a[rt]);
		return;
	}
	int m = (l + r) >> 1;
	build(l,m,rt<<1);
	build(m+1,r,rt<<1|1);
	a[rt] = min(a[rt<<1],a[rt<<1|1]);
}
int query(int l,int r,int x,int y,int rt)
{
	if(x <= l && y >= r)
		return a[rt];
	int m = (l + r) >> 1;
	int ret = 0x7fffffff;
	if(x <= m)
		ret = min(ret,query(l,m,x,y,rt<<1));
	if(y > m)
		ret = min(ret,query(m+1,r,x,y,rt<<1|1));
	return ret;
}

void update(int l,int r,int rt,int x)
{
	if(l == r)
		return;
	int m = (l + r) >> 1;
	if(x <= m)
		update(l,m,rt<<1,x);
	else
		update(m+1,r,rt<<1|1,x);
	a[rt] = min(a[rt<<1],a[rt<<1|1]);
}
int main()
{
	int n,m,x,y,k,len,i;
	int b[100];
	char str[100];
	scanf("%d %d",&n,&m);
	build(1,n,1);
	while(m--)
	{
		scanf("%s",str);
		for(i = 0,len = 0,k = 0; str[i]; i++)
		{
			if(str[i] >= '0' && str[i] <= '9')
			{
				k *= 10;
				k += str[i] - '0';
			}
			else
			{
				if(k)
				{
					b[len++] = k;
					k = 0;
				}
			}
		}
		if(str[0] == 'q')
			printf("%d\n",query(1,n,b[0],b[1],1));
		else
		{
			k = a[pos[b[0]]];
			for(i = 0;i < len - 1; i++)
			{
				a[pos[b[i]]] = a[pos[b[i+1]]];
			}
			a[pos[b[len-1]]] = k;
			for(i = 0;i < len; i++)
			{
				update(1,n,1,b[i]);
			}
		}
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: