RMQ with Shifts(未解决的题目)
编辑器加载中...
RMQ with Shifts
Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 5 Accepted Submission(s) : 2
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
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].
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}.
Input
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.
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
数组越界的代码:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstdio>
using namespace std;
#define Min(x,y) x<y?x:y
struct node
{
int l,r;
int min;
}sg_tree[1000000];
int f[1000100];
void make(int l1,int r1,int num)
{
if(l1<r1)
{
int mid=(l1+r1)>>1;
sg_tree[num].l=l1;
sg_tree[num].r=r1;
make(l1,mid,2*num);
make(mid+1,r1,2*num+1);
sg_tree[num].min=Min(sg_tree[2*num].min,sg_tree[2*num+1].min);
}
else if(l1==r1)
{
sg_tree[num].l=l1,sg_tree[num].r=r1;
sg_tree[num].min=f[l1];
}
}
void insert(int num,int index,int d)
{
int mid=(sg_tree[num].l+sg_tree[num].r)>>1;
if(sg_tree[num].l==sg_tree[num].r)
{
sg_tree[num].min=d;
return ;
}
if(index<=mid)
{
insert(2*num,index,d);
sg_tree[num].min=Min(sg_tree[2*num].min,sg_tree[2*num+1].min);
}
else
{
insert(2*num+1,index,d);
sg_tree[num].min=Min(sg_tree[2*num].min,sg_tree[2*num+1].min);
}
}
int query(int l,int r,int num)
{
int mid=(sg_tree[num].l+sg_tree[num].r)>>1;
if(l<=sg_tree[num].l&&r>=sg_tree[num].r)
return sg_tree[num].min;
else if(r<=mid)
return query(l,r,2*num);
else if(l>mid)
return query(l,r,2*num+1);
else
return Min(query(l,mid,2*num),query(mid+1,r,2*num+1));
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=1;i<=n;i++)
scanf("%d",&f[i]);
make(1,n,1);
while(m--)
{
char cmd[330];
scanf("%s",cmd);
// puts(cmd);
int l,r;
if(cmd[0]=='q')
{
l=cmd[6]-'0';
r=cmd[8]-'0';
//cout<<l<< " " <<r<<endl;
cout<<query(l,r,1)<<endl;;
}
else
{
int temp=0,array[300];
for(int i=6;cmd[i];i+=2)
{
array[temp++]=cmd[i]-'0';
}
// cout<<array[0]<< " " ;
int pre=f[array[0]];
for(int i=0;i<temp-1;i++)
{
insert(1,array[i],f[array[i+1]]);
f[array[i]]=f[array[i+1]];
}
insert(1,array[temp-1],pre);
f[array[temp-1]]=pre;
}
}
}
return 0;
}