zoukankan      html  css  js  c++  java
  • UVa 12299 RMQ with Shifts(移位RMQ)

    UVa 12299 - RMQ with Shifts(移位RMQ)

    Time limit: 1.000 seconds


    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

    在经典的RMQ(区间最值)问题中,给定数组A。对于每个询问(L,R) (L ≤ R),输出A[L], A[L + 1], ..., A[R]中的最小值。注意下标从1开始,即最左边的元素为A[1]。在这个问题中,数组A会发生些许变化:定义如下操作
    CN
     
    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.

    我们对A[i1], A[i2], ..., A[ik]执行循环左移。例如,A={6, 2, 4, 8, 5, 1, 4},则经过shift(2,4,5,7)后得到 {6, 8, 4, 5, 4, 1, 2}。再经过shift (1,2)得到8, 6, 4, 5, 4, 1, 2
    CN

     

    Input - 输入

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

    只有一组测试用例,起始位置有两个整数n, q (1 ≤ n ≤ 100,000, 1 ≤ q ≤ 250,000),分别表示整数数组A中的元素个数,询问的数量。下一行有n个不超过100,000的非负数,皆为数组A中的初始元素。随后q行每行包含一个操作。每个操作皆为一个不超过30个字符的字符串,且不含空格。全部操作均正确有效。
    
    注意:数据量很大,最好使用更快的I/O函数。
    CN

    Output - 输出

    For each query, print the minimum value (rather than index) in the requested range.

    对于每个询问,输出待求范围的最小值(非下标)。
    CN

     

    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
    

    题解

    一般的线段树。

    虽然说数据量大,意思也就不能用cin吧,scanf还是可以A的。

    一开始还以为需要用延迟更新,然后想了想30*25WO(NlogN)还是应该可以的,能简则简。

    代码中用的是自下往上的更新方式,目测比从上往下略快,可以跳过部分更新。

    代码 C++

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define mx 100005
     5 int tr[mx << 2], path[mx], iP, ts[mx];
     6 int build(int L, int R, int now){
     7     if (L > R) return mx;
     8     if (L == R) scanf("%d", tr + (path[++iP] = now));
     9     else{
    10         int mid = L + R >> 1, cL, cR;
    11         cL = build(L, mid, now << 1); cR = build(mid + 1, R, now << 1 | 1);
    12         tr[now] = std::min(cL, cR);
    13     }
    14     return tr[now];
    15 }
    16 int query(int L, int R, int now, int edL, int edR){
    17     if (edL <= L && R <= edR) return tr[now];
    18     int mid = L + R >> 1, cL, cR;
    19     if (edR <= mid) return query(L, mid, now << 1, edL, edR);
    20     if (mid < edL) return query(mid + 1, R, now << 1 | 1, edL, edR);
    21     cL = query(L, mid, now << 1, edL, mid); cR = query(mid + 1, R, now << 1 | 1, mid + 1, edR);
    22     return std::min(cL, cR);
    23 }
    24 void updata(int now, int n){
    25     int tmp, cL, cR;
    26     while (now >>= 1){
    27         tmp = std::min(tr[now << 1], tr[now << 1 | 1]);
    28         if (tmp == tr[now]) return;
    29         tr[now] = tmp;
    30     }
    31 }
    32 int main(){
    33     memset(tr, 127, sizeof(tr));
    34     int n, q, i, j, tmp;
    35     char op[20];
    36     scanf("%d%d", &n, &q);
    37     build(1, n, 1); getchar();
    38     while (q--){
    39         fread(op, sizeof(char), 6, stdin);
    40         if (*op == 'q'){
    41             for (i = 0; i < 2; ++i) scanf("%d", ts + i), getchar();
    42             printf("%d
    ", query(1, n, 1, ts[0], ts[1]));
    43         }
    44         else{
    45             for (j = 0; *op != ')'; ++j) scanf("%d", ts + j), *op = getchar();
    46             for (tmp = tr[path[ts[i = 0]]]; i < j - 1; ++i){
    47                 tr[path[ts[i]]] = tr[path[ts[i + 1]]];
    48                 updata(path[ts[i]], n);
    49             }
    50             tr[path[ts[i]]] = tmp;
    51             updata(path[ts[i]], n);
    52         }
    53         getchar();
    54     }
    55     return 0;
    56 }
  • 相关阅读:
    [Javascript] Data ownership, avoid accidently mutation
    [Next.js] Consume Next.js API routes with the SWR library on the client-side
    [ARIA] Read error message for the focused form field by using aria-describedby
    [ARIA] Group different DOM element in screen reader by using aria-labelledby
    [React] Handle HTTP Errors with React
    [Angular] Modify :before / :after value from Javascirpt
    [Javascript] Finding Sibling Elements
    [Javascript] Finding Parent Elements
    MAC之find与grep
    Android只播放gif动画
  • 原文地址:https://www.cnblogs.com/Simon-X/p/5995157.html
Copyright © 2011-2022 走看看