zoukankan      html  css  js  c++  java
  • CSU-1110 RMQ with Shifts (单点更新+区间最小值 zkw线段树)

    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, 85, 1, 4}, then shift(2, 4, 5, 7) yields {68, 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 nq (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

    看题目的开始可以知道,是一个求区间最小值的问题,可以用线段树来解决,看了后半段,感觉是单点更新问题,但看了数据范围时,有点蒙了,普通的操作会超时吧。。。卡了一段时间没敢写,然后,然后,竟然过了。。。唉,没经验啊。。。

    题意就是给出一段序列,有两种操作,第一种是区间查询最小值,第二种是shift,就是按照给出的位置的数据循环左移一位。

    代码如下:

    #include<iostream>
    #include<cstring>
    #include<sstream>
    #include<cstdio>
    
    using namespace std;
    const int N = 100000 + 5;
    const int INF = (1<<30);
    int T[N<<2],a[N],q[N],M,cnt;
    char ch[N];
    void Build(int n){
        int i;
        for(M=1;M<=n+1;M*=2);
        for(i=M+1;i<=M+n;i++) T[i]=a[cnt++];
        for(i=M-1;i;i--) T[i]=min(T[i<<1],T[i<<1|1]);
    }
    
    void Updata(int n,int V){
        for(T[n+=M]=V,n/=2;n;n/=2)
            T[n]=min(T[n<<1],T[n<<1|1]);
    }
    
    int Query(int s,int t){
        int minc = INF;
        for(s=s+M-1,t=t+M+1;s^t^1;s/=2,t/=2){
            if(~s&1) minc=min(minc,T[s^1]);
            if(t&1) minc=min(minc,T[t^1]);
        }
        return minc;
    }
    void Replace(char *ch,int &cur){
        cur = 0; int tmp=0;
        int len = strlen(ch);
        for(int i=0;i<len;i++)
            if(isdigit(ch[i])){
                tmp=tmp*10 + ch[i]-'0';
                if(i+1==len||!isdigit(ch[i+1])){
                    q[cur++] = tmp;
                    tmp = 0;
                }
            }
    }
    void solve_question(int m){
        int cur;
        for(int i=0;i<m;i++){
            scanf("%s",ch);
            if(ch[0]=='q'){
                Replace(ch,cur);
                printf("%d
    ",Query(q[0],q[1]));
            }else{
                Replace(ch,cur);
                int t = a[q[0]];
                for(int i=0;i<cur-1;i++)
                    a[q[i]] = a[q[i+1]];
                a[q[cur-1]] = t;
                for(int i=0;i<cur;i++)
                    Updata(q[i],a[q[i]]);
            }
        }
    }
    int main(){
        int n,m;
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        cnt = 1;
        Build(n);
        solve_question(m);
    }
     




  • 相关阅读:
    Cycle Sort
    使用finalize/dispose 模式提高GC性能(翻译)
    支持在控件标签间包含子控件 WebControl
    MongoDB 使用GridFS保存文件
    MongoDB学习笔记
    跨域名单点登录 part 1 设计蓝图(翻译)
    UserControl 用户自定义控件
    为什么90%的IT人员都不适合做老大?
    什么情况下你会毫不犹豫地辞职?
    Supervisor安装、配置、开启启动
  • 原文地址:https://www.cnblogs.com/Pretty9/p/7384052.html
Copyright © 2011-2022 走看看