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

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;

}

 


 

你可能感兴趣的:(with)