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*25W的O(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\n", 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 }
时间: 2024-11-05 05:26:29

UVa 12299 RMQ with Shifts(移位RMQ)的相关文章

UVa 12299 线段树 单点更新 RMQ with Shifts

因为shift操作中的数不多,所以直接用单点更新模拟一下就好了. 太久不写线段树,手好生啊,不是这错一下就是那错一下. PS:输入写的我有点蛋疼,不知道谁有没有更好的写法. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 using namespace std; 7 8 const

Uva 12299 带循环移动的RMQ(线段树)

题目链接:https://vjudge.net/contest/147973#problem/C 题意:传统的RMQ是一个不变的数组a求区间最值.现在要循环移动(往前移动). 分析:求区间问题,很容易想到线段树,西东就相当于单点更新. 建树,有两种方案,第一种是nlogn,就是不断的更新,更新logn,有n个数. 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 6 const int INF = 1000000000; 7 con

Uva 12299 RMQ with Shifts(线段树 + 单点更新 )

Uva 12299 RMQ with Shifts (线段树 + 单点更新) 题意: 对于给定的序列 x[i]给出一个操作 shift(a,b,c,d,e) 对应的是将 x[a]与x[b] x[b]与x[c] 这样相邻的两两交换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

UVa 12299 RMQ with Shifts(线段树)

线段树,没了.. ----------------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cctype> #define rep(i,n) for(int i=0;i<n

湖南省第七届大学生计算机程序设计竞赛 RMQ with Shifts (线段树)

RMQ with Shifts 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述     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 indic

nyoj 568——RMQ with Shifts——————【线段树单点更新、区间求最值】

RMQ with Shifts 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述     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 indic

C. RMQ with Shifts

C. RMQ with Shifts Time Limit: 1000ms Case Time Limit: 1000ms Memory Limit: 131072KB 64-bit integer IO format: %lld      Java class name: Main In the traditional RMQ (Range Minimum Query) problem, we have a static array A. Then for each query (L, R) 

【UVA】12299-RMQ with Shifts(线段树)

修改的时候由于数据很小,所以可以直接暴力修改,查询的时候利用线段树就行了. 14337858 12299 RMQ with Shifts Accepted C++ 0.282 2014-10-11 16:02:53 #include<cstdio> #include<vector> #include<cstring> #include<algorithm> using namespace std; #define lson pos<<1 #def

uva 12299 线段树 点相关的操作模板

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=502&page=show_problem&problem=3720 唯一值得一说的就是shift,变成更新点就行 这道题主要是测试下我做的算法模板 先贴模板 /**************************************************************** 2014.4 By Pilgr