首页 > 其他分享 >uva 12299 RMQ with Shifts(线段树单点更新初步应用)

uva 12299 RMQ with Shifts(线段树单点更新初步应用)

时间:2023-07-26 17:32:14浏览次数:61  
标签:... 12299 RMQ return int shift mid Shifts query


                              uva 12299 RMQ with Shifts


In the traditional RMQ (Range Minimum Query) problem, we have a static array A. Then for each query (L, R) (LR), 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


shift( i 1, i 2, i 3,..., i k)( i 1 < i 2 < ... < i k, 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)

Input 

There will be only one test case, beginning with two integers

n,

q (

1n100, 000,

1q250, 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:

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




题目大意:第一行输入两个整数(数据个数,操作个数), query(a,b)为查找区间a到b的最小值,并输出。shift(a,b,c,d...)为将a,b,c,d...全部左移,最左边的移动到最右边。

解题思路:线段树的单点更新。



#include<cstdio>
#include<algorithm>
using namespace std;
#define N 100000 * 4
int S[N], V[N], R[N], L[N];
void build(int n, int l, int r) {       //建树
	L[n] = l;
	R[n] = r;
	if (l == r) {
		S[n] = V[l];
		return ;
	}
	int mid = (l + r) / 2;
	build(n * 2, l, mid);
	build(n * 2 + 1, mid + 1, r);
	S[n] = min(S[n * 2], S[n * 2 + 1]);
}

void modify(int n, int x, int v) {       //更新

	if (L[n] == x && R[n] == x) {
		S[n] = v;
		return;
	}
	int mid = (L[n] + R[n]) / 2;

	if (x <= mid) 
		modify(n * 2, x, v);
	else 
		modify(n * 2 + 1, x, v);
	
	S[n] = min(S[n * 2], S[n * 2 + 1]);
}
 
int find(int n, int l, int r) {           //区间查找

	if (l <= L[n] && R[n] <= r) {
		return S[n];
	}
	int mid = (L[n] + R[n]) / 2;
	if(r <= mid) {
		return find(n * 2, l, r);	
	}
	else if (l > mid) {
		return find(n * 2 + 1, l, r);
	}
	else {
		return min( find(n * 2, l , r), find(2 * n + 1, l , r));
	}
}
int main() {
	int m, n;
	scanf("%d%d", &m, &n);
	int i;
	for (i = 1; i <= m; i++) 
		scanf("%d", &V[i]);
	
	build(1, 1, m);
	char s[100];
	while(n--){
		scanf("%s", s);
		if (s[0] == 'q') {
			int temp[2];
			sscanf(s,"query(%d,%d)",&temp[0],&temp[1]);
			printf("%d\n", find(1, temp[0], temp[1]));
		}
		else {
			int temp2[30] = {0}, cnt = 0,num;

			for (int k = 6; s[k] != ')'; k++) {
				if(s[k] == ',') {
					cnt++;
					continue;	
				}
				temp2[cnt] = (temp2[cnt] * 10) + s[k] - '0';
				
			}

			num = V[temp2[0]];
			for (int k = 0; k < cnt; k++) {
				modify(1, temp2[k], V[temp2[k + 1]]);
				V[temp2[k]] = V[temp2[k + 1]];
				}
			modify(1,temp2[cnt],num);
			V[temp2[cnt]] = num;
			}
	}
	return 0;
}




标签:...,12299,RMQ,return,int,shift,mid,Shifts,query
From: https://blog.51cto.com/u_16206136/6858303

相关文章

  • P6109 [Ynoi2019] rprmq1
    LuoguP6109[Ynoi2009]rprmq1LuoguP6109题目背景我谔谔本题读入量约13MB,输出量约7MB,请选择合适的输入输出方法题目描述有一个\(n\timesn\)的矩阵\(a\),初始全是\(0\),有\(m\)次修改操作和\(q\)次查询操作,先进行所有修改操作,然后进行所有查询操作。一次修改......
  • 洛谷 P6109 - [Ynoi2009] rprmq1
    首先将修改操作差分为\(l_1\)时刻给\([l_2,r_2]\)中的值\(+v\),\(r_1+1\)时刻给\([l_2,r_2]\)中的值\(-v\)。这样第\(i\)行的状态相当于执行\(1\simi\)时刻的操作后的状态。猫树分治,把一个询问挂在线段树上满足\(l\lel_1\lemid\ler_1\ler\)的区间\([l,r]\)......
  • 2023ACM暑假训练day 7-RMQ问题
    目录DAY7RMQ问题训练情况简介题DAY7RMQ问题训练地址:传送门训练情况简介2023-07-03星期一早上:下午:晚上:题题意:思路:......
  • Codeforces Round #291 (Div. 2)-D. R2D2 and Droid Army(RMQ)
    原题链接D.R2D2andDroidArmytimelimitpertestmemorylimitpertestinputoutputAnarmyof n droidsislinedupinonerow.Eachdroidisdescribedby m integers a......
  • POJ 2019 Cornfields(简单二维RMQ)
    思路:二维RMQ#include<cstdio>#include<cstring>#include<algorithm>usingnamespacestd;constintMAXN=255;intval[MAXN][MAXN];intdmin[MAXN][MAXN][8][8];intdmax[MAXN][MAXN][8][8];voidinitRMQ(intn,intm){for(inti=1;i<=n;i++)......
  • CF 1175E Minimal Segment Cover[RMQ]
    题目链接:http://codeforces.com/problemset/problem/1175/E 解题思路:预处理出每个点用一次可以到达最远的距离。那么某个点用两次可以到达最远距离就是他用一次到达最远距离的地方用一次到达的最远距离,所以我们可以去倍增。#include<bits/stdc++.h>usingnamespacestd;typed......
  • poj 2452(RMQ+二分)
    解题思路:这题实际上就是求某区间上的最值问题,可以先枚举区间的起始位置,然后二分去搜索比起始位置大的数且位置最远(这里可以用RMQ算法区间内的最小值),找到之后再利用RMQ算法找这段区间内的最大的,如果这段区间的长度比当前的最优值大,那么更新。详细的见代码。#include<iostream>#incl......
  • RMQ 问题的两种实现办法(线段树查询和稀疏表(Sparse Table表)查询)
    引言RMQ算法(RangeMinimum/MaximumQuery)是静态区间极值查询的高效算法,在各种算法竞赛中常常出现,虽然不会单独拿出来做一个题,但是经常作为题的一部分。依据所需实现的不同性能可以有多种写法,这里主要讲基于线段树和稀疏表(SparseTable)的两种方法。线段树实现RMQ线段树是维护......
  • hdu:这是真正的水题(RMQ)
    ProblemDescription在缺水的地方,水是非常有限的资源,所以人们常常为争夺最大的水源而战。给定一系列水源,用a1,a2,a3,…,an代表水源的大小。给定一组查询,每个查询包含2整数L和R,请找出L和R之间最大的水源。Input输入数据首先给定一个整数T(T≤10)表示测试用例的数量。......
  • 最近公共祖先 RMQ
    就是把LCA问题转化为RMQ问题转化之前先要了解欧拉序列:对一棵树进行DFS,无论是第一次访问还是回溯,每次到达一个结点时都将编号记录下来,可以得到一个长度为2n-1的序列,这个序列被称作这棵树的欧拉序列。比如下面这个树:(2连3和4)1->2->3        ->4->5其序列就是123......