rmq

RMQ Terminology

会有一股神秘感。 提交于 2019-12-03 08:14:26
原创转载请注明出处: https://www.cnblogs.com/agilestyle/p/11784644.html Message 消息,消息是不具名的,由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括 routing-key:路由键 priority:相对于其他消息的优先权 delivery-mode:指出该消息可能需要持久性存储 Producer 消息的生产者,是一个向交换器发布消息的客户端应用程序。 Consumer 消息的消费者,表示一个从消息队列中取得消息的客户端应用程序。 Exchange 交换器,用来接收生产者发送的消息并将这些消息路由给服务器中的队列 RMQ中的交换器类型: direct:发布与订阅、完全匹配 fanout:广播 topic:主题、规则匹配 Binding 绑定,用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表。 Queue 消息队列,用来保存消息直到发送给消费者。它是消息的容器,也是消息的终点。一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其处理。 routing key 路由键:RMQ决定消息该投递到哪个队列的规则。 队列通过路由键绑定到交换器 消息发送到代理服务器时

RMQ问题

匿名 (未验证) 提交于 2019-12-03 00:43:02
一:引入 RMQ 是求某个区间内的最大值或最小值。 RMQ 的求解方法----- ST算法 二:ST算法 ST算法 利用了 动态规划 。这里假设有arr[1..n]一组数,设f[i][j]表示从 a[i] a[i+(2^j)-1] 的最大值,也就是以a[i]为起点的连续 2^j 个数的最大值。由于数个数有2^j个,所以从中间平均分为 两部分 ,每一部分的数的个数为 2^(j-1) 个。 动态规划最优化原理 。所以,我们可以得到这样的一个状态转移方程: f[i][j]=max(f[i][j-1] , f[i+2^(j-1)][j-1] ,边界为 .。我们可以用 (n*log(n))的时间复杂度预处理f数组; 2.询问: 若我们要询问区间[L,R]的最大值,那么,我们需要先求出最大的x满足 2^x <=R-L+1 ,那么区间[L,R]的最大值便是 ;其中:第一个区间表示 L 到 L+2^x-1 的最大值,第二个区间表示 R-2^x+1 到 R 的最大值。现在看一下,是不是成功的求出了最大值?(因为2^x <=R-L+1 就说明 第二区间的左端点在L的右边,两者去掉重复的线段正好是L到R(有重复没关系,因为max这个函数是不管这些的)) 三:一点小技巧 因为cmath中的log2的函数 效率不高 ,所以,还是自己写吧。 四:代码 ST算法模板题面――点击转入luogu #include

springCloud Stream

匿名 (未验证) 提交于 2019-12-03 00:41:02
spring Cloud Steam 生产者配置 设置生产者的输入输出通道 package net.happyeasygo.hotel.mq.interf; import org.springframework.cloud.stream.annotation.Input; import org.springframework.cloud.stream.annotation.Output; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.SubscribableChannel; public interface OrderProcessor { String INPUT_ORDER = "inputOrder"; String OUTPUT_ORDER = "outputOrder"; @Input(INPUT_ORDER) SubscribableChannel inputOrder(); @Output(OUTPUT_ORDER) MessageChannel outputOrder(); } 生产者发送消息 @EnableBinding(OrderProcessor.class) public class PayCallBackController

约束RMQ

匿名 (未验证) 提交于 2019-12-03 00:40:02
不知道为什么网上找不到太多相关的资料,所以写一个小总结,并附有能用的代码。 约束RMQ,就是RMQ区间必须满足两项之差最大为1,采用ST表的话,这时候有 O(n)建表,O(1)查询 的优秀复杂度 求LCA,通过DFS把原树转化为深度序列,就等价于求区间最小值 (取到的位置) 由于DFS的性质,该序列两个数之间显然相差1,所以可以使用约束RMQ解决 先总体概括一下做法:把原序列分块,块内预处理,块间做ST表 分块大小定为L=log(n)/2,这样共分D=n/L块,对这D个数(块内最小值)做正常ST表,建表复杂度O(Dlog(D))=O((n/L)(log(n)-log(L))=O(n) 我们要保证每个步骤都是O(n)的,log(n)/2正好消去了ST建表时的log 但在此之前,我们得处理出块内的最小值,该怎么做呢?一个正常想法就是枚举每个数,一共是O(n)复杂度 但是,这样做虽然留下了每块的最小值以及其取到的位置,若考虑查询块的一个区间,而这个区间恰好取不到最小值,这时候只能暴力枚举,就破坏了查询O(1)了 至此我们仍没有使用其±1的特殊性质,现在考虑一下。 块内一共log(n)/2个数,由乘法原理可知,本质不同的块有U=2^(log(n)/2)=n^(1/2)个,我们不妨处理出每个这种块,复杂度Ulog(n)/2,这个函数增长是小于线性的,可以认为是O(n) 这样

LGOJ P4137 Rmq Problem / mex

匿名 (未验证) 提交于 2019-12-03 00:17:01
有一个长度为n的数组 \({a_1,a_2,…,a_n}\) 。 \(m\) 次询问,每次询问一个区间内最小没有出现过的自然数。 第一行 \(n\) , \(m\) 。 第二行为 \(n\) 个数。 从第三行开始,每行一个询问 \(l\) , \(r\) 。 一行一个数,表示每个询问的答案。 输入 #1 5 5 2 1 0 2 1 3 3 2 3 2 4 1 2 3 5 输出 #1 1 2 3 0 3 对于30%的数据:1<=n,m<=1000 对于100%的数据:1<=n,m<=200000,0<=ai<=10^9,1<=l<=r<=n 难点在 \(add\) 函数上。给我的教训是,变量名最好要有实际意义,不要盲目追求短小,否则巨难debug。 ↓拿到了一个新的元素,检查是否是刚刚加入的。如果是,并且这个数是原来区间的 \(mex\) ,那么就暴力更新新的 \(mex\) 即可。 inline void add(int pos) { cnt[a[pos]]++; if(cnt[a[pos]]==1&&now==a[pos]) { int tmp=a[pos]; while(cnt[tmp]!=0)tmp++; now=tmp; return; } } 开 \(o2\) 会WA两个点,我猜是 \(cmp\) 函数的锅: return (belong[i.l] ^ belong[j

树上倍增求LCA(RMQ)

匿名 (未验证) 提交于 2019-12-03 00:13:02
板子(反正我只是个垃圾) //树上倍增求LCA(RMQ),其实就是个简单的二进制拆分问题 //正确性很容易证明,不证了 //思想:eg: 求x节点和y节点的Lca,比较 x 与 y 节点的深度,将树中深的节点跳到 //与浅的节点相同深度(由大到小循环),如果刚好为深度浅的节点,那么就找到了,否则一起向 //上跳,找到最小的j使得他们所跳的位置不同,但父节点是相同的,返回所跳位置的父节点就好了 #include<bits/stdc++.h>//板子 using namespace std; const int maxn = 1000010; int head[maxn]; int deep[maxn];//节点深度 struct{ int v,net; }edge[maxn];//链式前向星(ORZ,向大佬低头) int n,m,root,cnt; int f[maxn][21];//每个当前节点的第2 ^ j次方是哪个节点 inline void add_edge(int x,int y) { edge[cnt].v = y; edge[cnt].net = head[x]; head[x] = cnt++; }//加边 void dfs(int cur) { for(int i=head[cur];i!=-1;i=edge[i].net) { if(!deep[edge[i].v

poj2019 二维RMQ裸题

匿名 (未验证) 提交于 2019-12-02 23:49:02
Cornfields Time Limit: Memory Limit: Total Submissions: 8623 Accepted: Description Input Output Sample Input 5 3 1 5 1 2 6 3 1 3 5 2 7 7 2 4 6 1 9 9 8 6 5 0 6 9 3 9 1 2 Sample Output 5C++代码 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <set> 6 #include <vector> 7 #include <map> 8 #include <queue> 9 #include <set> 10 #include <math.h> 11 #include <algorithm> 12 using namespace std; 13 #define MAXN 250 + 5 14 int dp[MAXN][MAXN][20]; 15 int dp1[MAXN][MAXN][20]; 16 int a[MAXN][MAXN]; 17 int n,m; 18 void st(){ 19 for(int i=1;i<=n;i++) 20 for(int k=0;(1

RMQ简述

匿名 (未验证) 提交于 2019-12-02 23:32:01
RMQ主要用于区间内最值的 多组 查询,暴力枚举会超时的情况下 (当然如果你会线段树当我没说) 主要思想就是倍增+dp #include<bits/stdc++.h> using namespace std; const int N = 1e5+5; int dp[N][20]; int a[N]; void RMQ_build(int n){ for(int i=0; i<=n;i++) dp[i][0]=a[i]; for(int j = 1;(1<<j)<=n;j++) { for(int i = 1 ; i+(1<<j)-1 <= N;i++) dp[i][j]=min(dp[i][j-1],dp[i+(1<<j-1)][j-1]);//找 最 值 } } int RMQ_query(int l,int r) { int k=(int)(log((double)(r-l+1))/log(2.0)); printf("%d ",min(dp[l][k],dp[r-(1<<k)+1][k])); } int main(){ int m,n,l,r; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } RMQ_build(n); for(int i=0;i<m;i++){ scanf("%d%d",

洛谷 1816 忠诚

怎甘沉沦 提交于 2019-12-02 00:07:07
原来这样区间查询的题目原来是要用线段树的,但是…… 这题可以用 ST表(RMQ) #include<bits/stdc++.h> using namespace std; const int N=1e5+10; int m,n,l,r,k,a[N][25]; void RMQ(int n) { for(int j=1;j<=20;j++) for(int i=1;i<=n;i++) if(i+(1<<j)-1<=n) a[i][j]=min(a[i][j-1],a[i+(1<<(j-1))][j-1]); } int main() { scanf("%d%d",&m,&n); for(int i=1;i<=m;i++) scanf("%d",&a[i][0]); RMQ(m); while(n--) { scanf("%d%d",&l,&r); k=log2(r-l+1); printf("%d ",min(a[l][k],a[r-(1<<k)+1][k])); } puts(""); return 0; } 来源: https://www.cnblogs.com/Siv0106/p/11722389.html

浅谈——RMQ

大兔子大兔子 提交于 2019-12-01 06:12:37
图论基础知识 感谢: https://www.cnblogs.com/yoke/p/6949838.html 1.RMQ是啥? 摘自 百度 其实你不用看,百度的概念有几个看得懂的? 对于长度为n的数列A。 回答若干询问RMQ(A[i,j])(i,j<=n), 返回数列A中下标在i,j之间的最小/大值。 2.有什么方法? 普通遍历查询 ,O(1)-O(N) 线段树 ,O(N)-O(logN) DP ,O(NlogN)-O(1) RMQ标准算法 ,O(N)-O(1) 我们这里讲的是DP算法——> ST算法 ST算法是一种比较高效的 在线算法 。 所谓在线算法,是指用户每输入一个查询便马上处理一个查询。该算法一般 用较长的时间做预处理,待信息充足以后便可以用较少的时间回答每个查询。 ST(Sparse Table)算法是一个非常有名的在线处理RMQ问题的算法,它可以在O(nlogn)时间内进行预处理,然后在O(1)时间内回答每个查询。 3.怎么做? 首先是 预处理 ,用动态规划(DP)解决。 设A[i]是要求区间最值的数列, F[i, j]表示从第i个数起连续2^j个数中的最大值。 (DP的状态) 例如: A数列为:3 2 4 5 6 8 1 2 9 7 F[1,0]表示第1个数起,长度为2^0=1的最大值,其实就是3这个数。 同理 F[1,1] = max(3,2) = 3; F[1