关闭

uva_12299 RMQ with Shifts

868人阅读 评论(0) 收藏 举报

 RMQ with Shifts 

In the traditional RMQ (Range Minimum Query) problem, we have a static array A. Then for eachquery (L, R) (L$ \le$R), 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 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.

Input 

There will be only one test case, beginning with two integers n, q (1$ \le$n$ \le$100, 000, 1$ \le$q$ \le$250, 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

#include<stdio.h>
#include<math.h>
#define L(i) i<<1
#define R(i) i<<1|1
#define N 100011
/*
线段树,注意这里是离散的点更新,这些点是有序的,update(l,r,id)中
l、r表示更新的点的下表,若左右孩子都更新时for()寻找断点
状态不佳,l、r的含义糊涂了好久
*/
struct node{
    int l,r,val;
    int mid(){return (l+r)/2;}
}st[N<<2];
int min(int a,int b){
    return a<b?a:b;
}
char str[33];
int a[N],com[33],cnt;
int getcom(){
    int i=6,sum=0,f;
    if(str[0]=='q')
        f=1;
    else
        f=0;
    for(;str[i];++i)
    {
        sum=0;
        for(;str[i]!=','&&str[i]!=')';++i)
            sum=sum*10+(str[i]-'0');//状态不佳,这里写成“+=” RE了无数
        com[cnt++]=sum;

    }
    return f;
}
void build(int l,int r,int id)
{
    st[id].l=l;
    st[id].r=r;
    if(l==r)
    {
        st[id].val=a[l];
        return ;
    }
    int mid=st[id].mid();
    build(l,mid,L(id));
    build(mid+1,r,R(id));
    st[id].val=min(st[L(id)].val,st[R(id)].val);
}
int query(int l,int r,int id)
{
    if(st[id].l==l&&st[id].r==r)
        return st[id].val;
    int mid=st[id].mid();
    if(mid>=r)
        return query(l,r,L(id));
    else if(mid<l)
        return query(l,r,R(id));
    else
        return min(query(l,mid,L(id)),query(mid+1,r,R(id)));
}
void update(int l,int r ,int id)
{
    if(st[id].l==st[id].r)
        st[id].val=a[st[id].l];
    else
    {
        int mid=st[id].mid();
        if(mid>=com[r])
            update(l,r,L(id));
        else if(mid<com[l])
            update(l,r,R(id));
        else
        {
            int i;
            for(i=l;com[i]<=mid;++i);
            update(l,i-1,L(id));
            update(i,r,R(id));
        }
        st[id].val=min(st[L(id)].val,st[R(id)].val);
    }
}
int main()
{
    int n,q,i,t,f;
    scanf("%d%d",&n,&q);
    for(i=1;i<=n;++i)
        scanf("%d",&a[i]);
    build(1,n,1);
    while(q--)
    {
        scanf("%s",str);
        cnt=0;
        f=getcom();
        if(f)
        {
            printf("%d\n",query(com[0],com[1],1));
        }
        else
        {
            --cnt;
            t=a[com[0]];
            for(i=0;i<cnt;++i)
                a[com[i]]=a[com[i+1]];
            a[com[i]]=t;
            update(0,cnt,1);
        }
    }
    return 0;
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:335813次
    • 积分:6321
    • 等级:
    • 排名:第4020名
    • 原创:308篇
    • 转载:24篇
    • 译文:0篇
    • 评论:46条
    我的微博
    最新评论