zoukankan      html  css  js  c++  java
  • RMQ with Shifts(线段树)

    RMQ with Shifts

    Time Limit:1000MS     Memory Limit:65535KB     64bit IO Format:%I64d & %I64u

    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
    

    Hint



    //线段树的应用,不是很难,写出来还是对线段树有更深一点的了解的

      1 #include <stdio.h>
      2 #include <string.h>
      3 
      4 #define MAXN 100005
      5 
      6 struct Node
      7 {
      8     int min;
      9     int l,r;
     10 }node[3*MAXN];//节点
     11 int pos[MAXN];//记录叶节点的位置
     12 int num[MAXN];//记录最开始的数
     13 int shift[50];//记录shift里的数
     14 
     15 int Min(int a,int b)
     16 {
     17     return a<b?a:b;
     18 }
     19 
     20 int Build(int left,int right,int k)
     21 {
     22     node[k].l=left;
     23     node[k].r=right;
     24     if (left==right)//到叶节点
     25     {
     26         node[k].min=num[left];
     27         pos[left]=k;
     28         return node[k].min;
     29     }
     30     int mid=(left+right)/2;
     31 
     32     node[k].min=Min(Build(left ,mid,2*k),Build(mid+1,right,2*k+1));
     33     return node[k].min;
     34 }
     35 
     36 int Query(int left,int right,int k)
     37 {
     38     if (left==node[k].l&&right==node[k].r)
     39     {
     40         return node[k].min;
     41     }
     42     int mid=(node[k].l+node[k].r)/2;
     43     if (left>mid) return Query(left,right,2*k+1);
     44     else if (right<=mid) return Query(left,right,2*k);
     45     return Min(Query(left,mid,2*k),Query(mid+1,right,2*k+1));
     46 }
     47 
     48 void Update(int k)
     49 {
     50     k/=2;
     51     while (k!=0)
     52     {
     53         node[k].min=Min(node[2*k].min,node[2*k+1].min);
     54         k/=2;
     55     }
     56 }
     57 
     58 int Get_shift(char str[])
     59 {
     60     int i,j;
     61     int n=0;
     62     int len=strlen(str);
     63     for (i=6;i<len;i++)
     64     {
     65         int temp=0;
     66         for (j=i;str[j]!=','&&str[j]!=')';j++)
     67         {
     68             temp+=str[j]-'0';
     69             temp*=10;
     70         }
     71         temp/=10;
     72         shift[++n]=temp;
     73         i=j;
     74     }
     75     return n;
     76 }
     77 
     78 int main()
     79 {
     80     int n,m;
     81     int i,j;
     82     scanf("%d%d",&n,&m);
     83     for (i=1;i<=n;i++)
     84         scanf("%d",&num[i]);
     85 
     86     Build(1,n,1);              //递归建树
     87     char str[50];
     88     int left,right;
     89 
     90     for (i=1;i<=m;i++)
     91     {
     92         scanf("%s",&str);
     93         if (str[0]=='q')
     94         {
     95             left=0,right=0;
     96             for (j=6;str[j]!=',';j++)
     97             {
     98                 left+=str[j]-'0';
     99                 left*=10;
    100             }
    101             left/=10;
    102             for (j++;str[j]!=')';j++)
    103             {
    104                 right+=str[j]-'0';
    105                 right*=10;
    106             }
    107             right/=10;
    108             printf("%d
    ",Query(left,right,1));//查找区间内最小的
    109         }
    110         if (str[0]=='s')
    111         {
    112             int shift_num=Get_shift(str);//获得shift里面的数
    113 
    114             int temp=node[pos[shift[1]]].min;
    115             for (j=2;j<=shift_num;j++)
    116                 node[pos[shift[j-1]]].min=node[pos[shift[j]]].min;
    117             node[pos[shift[j-1]]].min=temp;
    118             
    119             for (j=1;j<=shift_num;j++)
    120                 Update(pos[shift[j]]);
    121         }
    122 
    123     }
    124     return 0;
    125 }
    View Code
    
    
    



  • 相关阅读:
    165. Compare Version Numbers
    164. Maximum Gap
    3、桶排序
    162. Find Peak Element
    160. Intersection of Two Linked Lists
    155. Min Stack
    154. Find Minimum in Rotated Sorted Array II
    153. Find Minimum in Rotated Sorted Array
    Linux/Unix系统编程手册 第二章:基本概念
    Linux/Unix系统编程手册 第一章:历史和标准
  • 原文地址:https://www.cnblogs.com/haoabcd2010/p/5782022.html
Copyright © 2011-2022 走看看