RMQ with Shifts

RMQ with Shifts

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 3
描述
    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 
来源

湖南省第七届大学生计算机程序设计竞赛


 思路:

     与基本的线段树差不多,只要理解他的移位就行了。如1,4,6. 1,4,6->4,1,6->4,6,1.这为数组下标,按下标将数组值交换就行了。


AC代码:


#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cstdio>
using namespace std;
#define T 300005
#define inf 0x3f3f3f3f
int n,m,a[T],b[T];
struct node
{
	int L,R;
	int min;
}tree[T<<2];
void PushUp(int root)
{
	tree[root].min = min(tree[root<<1].min,tree[root<<1|1].min);
}
void Build(int root,int L,int R)
{
	tree[root].L = L,tree[root].R = R;
	tree[root].min = inf;
	if(L==R){
		tree[root].min = a[L];
		return;
	}
	int mid = (L+R)>>1;
	Build(root<<1,L,mid);
	Build(root<<1|1,mid+1,R);
	PushUp(root);
}
int qurey(int root,int L,int R)
{
	if(tree[root].L==L&&tree[root].R==R){
		return tree[root].min;
	}
	if(R<=tree[root<<1].R){
		return qurey(root<<1,L,R);
	}
	else if(L>=tree[root<<1|1].L){
		return qurey(root<<1|1,L,R);
	}
	else{
		int mid = (tree[root].L+tree[root].R)>>1;
		int a = qurey(root<<1,L,mid);
		int b = qurey(root<<1|1,mid+1,R);
		return min(a,b);
	}
}
void UpDate(int root,int pos,int val)
{
	if(tree[root].L == tree[root].R){
		tree[root].min = val;
		return; 
	}
	if(pos<=tree[root<<1].R){
		UpDate(root<<1,pos,val);
	}
	else {
		UpDate(root<<1|1,pos,val);
	}
	PushUp(root);
}
int main()
{
    /*freopen("input.txt","r",stdin);*/
	int i,j,k,c;
	char str[6];
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;++i)
		scanf("%d",&a[i]);
	scanf("\n");
	Build(1,1,n);
	while(m--)
	{
		c=0;
		scanf("%c%c%c%c%c%c",&str[0],&str[1],&str[2],&str[3],&str[4],&str[5]);
		if(str[0]=='q')
		{
			scanf("%d,%d)\n",&j,&k);
			printf("%d\n",qurey(1,j,k));
		}
		else
		{
			while(scanf("%d,",&b[c++])==1);
			 scanf(")\n");  
			for(i=1;i<c-1;++i){
				a[b[i]]^=a[b[i-1]];
				a[b[i-1]] = a[b[i]]^a[b[i-1]];
				a[b[i]] = a[b[i-1]]^a[b[i]];
				UpDate(1,b[i],a[b[i]]),UpDate(1,b[i-1],a[b[i-1]]);
			}
		}
	}
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值