RMQ with Shifts
RMQ with Shifts |
In the traditional RMQ (Range Minimum Query) problem, we have a static array A. Then for eachquery (L, R) (LR), we report the minimum value among A[L],A[L + 1], ..., A[R]. Note that theindices start from 1, i.e. the left-most element isA[1].
In this problem, the array A is no longer static: we need to support another operation
shift(
i
1,
i
2,
i
3,...,
i
k)(
i
1 <
i
2 < ... <
i
k,
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.
Input
There will be only one test case, beginning with two integers n, q ( 1n100, 000, 1q250, 000),the number of integers in array A, and the number of operations. The next line contains n positiveintegers not greater than 100,000, the initial elements in array A. Each of the next q lines contains anoperation. Each operation is formatted as a string having no more than 30 characters, with no spacecharacters inside. All operations are guaranteed to be valid.
Warning: The dataset is large, better to use faster I/O methods.
Output
For each query, print the minimum value (rather than index) in the requested range.Sample Input
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)
Sample Output
1 4 6
解决方案:这题只涉及了基本的线段树点的修改,区间最大值的查询。.。。。忽然发现,代码贴错了,,,,,
code:
<pre name="code" class="cpp">#include<iostream>
#include<cstdio>
#include<cstring>
#define MMAX 100003
using namespace std;
int Min[4*MMAX];
int n,q,_min;
int Q[100],k,x,v;
void push_up(int rt)
{
int l=rt*2,r=rt*2+1;
Min[rt]=min(Min[l],Min[r]);
}///往上更新维护数组
void build(int rt,int L,int R)
{
if(L==R)
{
scanf("%d",&Min[rt]);
// cout<<rt<<endl;
return ;
}
else
{
int M=(L+R)/2;
build(rt*2,L,M);
build(rt*2+1,M+1,R);
push_up(rt);
}
}///线段树的建立
void query(int rt,int L,int R,int l,int r)
{
if(l<=L&&r>=R)
{
_min=min(_min,Min[rt]);
}
else
{
int M=(L+R)/2;
if(l<=M) query(rt*2,L,M,l,r);
if(r>M) query(rt*2+1,M+1,R,l,r);
}
}///区间查询
void update(int rt,int L,int R)
{
if(L==R)
{
Min[rt]=v;
}
else
{
int M=(L+R)/2;
if(Q[x]<=M)
{
update(rt*2,L,M);
}
else update(rt*2+1,M+1,R);
Min[rt]=min(Min[rt*2],Min[rt*2+1]);
}
}///单点修改
void getnum(char str[])
{
int len=strlen(str);
k=0;
for(int i=6; i<len-1; i++)
{
if(str[i]==',')
{
k++;
continue;
}
Q[k]*=10;
Q[k]+=str[i]-'0';
}
}
int main()
{
char str[40];
while(~scanf("%d%d",&n,&q))
{
build(1,1,n);
for(int i=0; i<q; i++)
{
memset(Q,0,sizeof(Q));
scanf("%s",str);
getnum(str);
if(str[0]=='q')
{
_min=MMAX;
query(1,1,n,Q[0],Q[1]);
printf("%d\n",_min);
}
else
{
int temp;
_min=MMAX;
query(1,1,n,Q[k],Q[k]);
temp=_min;
_min=MMAX;
query(1,1,n,Q[0],Q[0]);
// cout<<k<<endl;
x=k,v=_min;
// cout<<v<<endl;
update(1,1,n);
for(x=0; x<k-1; x++)
{
_min=MMAX;
query(1,1,n,Q[x+1],Q[x+1]);
v=_min;
update(1,1,n);
}
x=k-1;
v=temp;
update(1,1,n);
}
}
}
return 0;
}