您的位置:首页 > 理论基础 > 数据结构算法

RMQ with Shifts

2015-09-23 00:28 381 查看


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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构