湖南省赛七 RMQ with Shifts 裸的线段树

RMQ with Shifts

Time Limit:1000MS    Memory Limit:65535KB    64bit IO Format:

Appoint description:

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].

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.

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

解题思路:
线段树,查点改点,没有技术含量
不过写的时候还是会出现小bug,这东西一不练就有点生疏
多练啊

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn = 100005;
const int inf = 0x3f3f3f3f;
int minv[maxn<<2];

bool cmp(int x,int y) {
    return x>y;
}
void pushup(int rt) {
    minv[rt] = min(minv[rt<<1],minv[rt<<1|1]) ;
}
void build(int l,int r,int rt) {
    //setv[rt] =  0 ;
    if(l==r) {
        scanf("%d",&minv[rt]);
        return ;
    }
    int m = (l+r)>>1 ;
    build(lson);
    build(rson);
    pushup(rt);
}

void update(int p,int s,int l,int r,int rt) {
    if(l==r){
        minv[rt] =s ;
        return ;
    }
    int m = (l+r)>>1 ;
    if(p<=m)update(p,s,lson);
    else update(p,s,rson);
    pushup(rt) ;
}
int query(int L,int R,int l,int r,int rt) {
    int ret =inf;
    if(L<=l&&r<=R) {
        return minv[rt] ;
    }
    int m = (l+r)>>1 ;
    if(L<=m)ret=min(ret,query(L,R,lson));
    if(R>m)ret=min(ret,query(L,R,rson));
    return ret ;
}
int n,q ;
int main() {
    while(~scanf("%d%d",&n,&q)) {
        char op[35];
        int arry[35];
        int arry2[35];
        memset(minv,0,sizeof(minv));
        memset(op,0,sizeof(op));
        memset(arry,0,sizeof(arry));
        memset(arry2,0,sizeof(arry2));
        build(1,n,1) ;

        while(q--){
            scanf("%s",op);
            if(op[0]=='q') {
                int a,b;
                sscanf(op,"query(%d,%d)",&a,&b);
                printf("%d\n",query(a,b,1,n,1));
            } else {
                int len=strlen(op);
                int numarry=0 ;
                int num = 0 ;
                for(int i=6;i<len-1;i++){
                    if(op[i]!=','){
                        num*=10;
                        num+=op[i]-'0';
                        arry[numarry] = num ;
                    }else{
                        numarry++;
                        num=0;
                    }
                }
                numarry++;


//                for(int i=0;i<numarry;i++) {
//                    printf("%d ",arry[i]);
//                }printf("\n");

                for(int i=0;i<numarry;i++) {
                    arry2[i] = query(arry[i],arry[i],1,n,1);
                }
                //sort(arry2,arry2+numarry,cmp);
                int x = arry2[0];
                for(int i=0;i<numarry-1;i++){
                    arry2[i]=arry2[i+1];
                }
                arry2[numarry-1] = x;
                for(int i=0;i<numarry;i++) {
                    update(arry[i],arry2[i],1,n,1);
                }
            }
        }
    }
    return 0;
}

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值