RMQ 与 LCA-ST算法
RMQ算法
区间求最值的算法,用区间动态规划(nlogn)预处理,查询O(1)
http://blog.csdn.net/y990041769/article/details/38405063
(POJ 3264)
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<queue>
#include<string>
#include<sstream>
#define eps 1e-9
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define MAXN 1005
#define MAXM 40005
#define INF 0x3fffffff
#define PB push_back
#define MP make_pair
#define X first
#define Y second
#define clr(x,y) memset(x,y,sizeof(x));
using namespace std;
typedef long long LL;
int i,j,k,n,m,x,y,T,ans,big,cas,num,len;
bool flag;
int a[],mm[][],mi[][]; void rmq()
{
for (int i=;i<=n;i++)
{
mm[i][]=mi[i][]=a[i];
}
for (int j=;(<<j)<=n;j++)
{
for (int i=;i+(<<j)-<=n;i++)
{
mm[i][j]=max(mm[i][j-],mm[i+(<<(j-))][j-]);
mi[i][j]=min(mi[i][j-],mi[i+(<<(j-))][j-]);
}
}
} int getans(int l,int r)
{
int k=;
while ((<<(k+))<=r-l+) k++;
int ans1=max(mm[l][k],mm[r-(<<k)+][k]);
int ans2=min(mi[l][k],mi[r-(<<k)+][k]);
return ans1-ans2;
} int main()
{
while (~scanf("%d%d",&n,&m))
{
clr(mm,);clr(mi,);
for (i=;i<=n;i++) scanf("%d",&a[i]);
rmq();
for (i=;i<=m;i++)
{
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",getans(l,r));
}
} return ;
}
大概看了看求LCA的ST算法,其思路很简单,就是树形转线性,
如果求a与b的最近公共祖先,就是确定first[a]~first[b]中深度最小的点,即求区间最小值,用RMQ维护即可。
http://blog.csdn.net/y990041769/article/details/40887469
hdu2586
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<queue>
#include<string>
#include<sstream>
#define eps 1e-9
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define MAXN 80005
#define MAXM 80005
#define INF 0x3fffffff
#define PB push_back
#define MP make_pair
#define X first
#define Y second
#define clr(x,y) memset(x,y,sizeof(x));
using namespace std;
typedef long long LL;
int i,j,k,n,m,x,y,T,ans,big,cas,num,len;
bool flag; int edge,head[MAXN],id[MAXN],dir[MAXN],first[MAXN],R[MAXN],vis[MAXN],tot;
int dp[MAXN][];
struct edgenode
{
int to,next,w;
} G[MAXM]; void add_edge(int x,int y,int w)
{
G[edge].to=y;
G[edge].w=w;
G[edge].next=head[x];
head[x]=edge++;
} void dfs(int u,int dep)
{
vis[u]=true;id[++tot]=u;
first[u]=tot;R[tot]=dep;
for (int i=head[u];i!=-;i=G[i].next)
{
int v=G[i].to;
if (!vis[v])
{
int w=G[i].w;
dir[v]=dir[u]+w;
dfs(v,dep+);
id[++tot]=u; R[tot]=dep;
}
}
} void ST(int n)
{
for (int i=;i<=n;i++)
{
dp[i][]=i;
}
for (int j=;(<<j)<=n;j++)
{
for (int i=;i+(<<j)-<=n;i++)
{
int a=dp[i][j-],b=dp[i+(<<(j-))][j-];
if (R[a]<R[b]) dp[i][j]=a; else dp[i][j]=b;
}
}
} int RMQ(int l,int r)
{
int k=;
while ((<<(k+))<=r-l+) k++;
int a=dp[l][k],b=dp[r-(<<k)+][k];
return R[a]<R[b]?a:b;
} int LCA(int u,int v)
{
int x=first[u],y=first[v];
if (x>y) swap(x,y);
return id[RMQ(x,y)];
} int main()
{
scanf("%d",&T);
while(T--)
{
memset(head,-,sizeof(head));
edge=;tot=;
scanf("%d%d",&n,&m);
for (i=;i<n;i++)
{
int x,y,d;
scanf("%d%d%d",&x,&y,&d);
add_edge(x,y,d);
add_edge(y,x,d);
}
memset(vis,,sizeof(vis));
dfs(,);
ST(*n-);
for (i=;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
int lca=LCA(u,v);
printf("%d\n",dir[u]+dir[v]-*dir[lca]);
}
}
return ;
}
RMQ 与 LCA-ST算法的更多相关文章
- [CF 191C]Fools and Roads[LCA Tarjan算法][LCA 与 RMQ问题的转化][LCA ST算法]
参考: 1. 郭华阳 - 算法合集之<RMQ与LCA问题>. 讲得很清楚! 2. http://www.cnblogs.com/lazycal/archive/2012/08/11/263 ...
- RMQ问题之ST算法
RMQ问题之ST算法 RMQ(Range Minimum/Maximum Query)问题,即区间最值问题.给你n个数,a1 , a2 , a3 , ... ,an,求出区间 [ l , r ]的最大 ...
- hdu-3078 Network(lca+st算法+dfs)
题目链接: Network Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) P ...
- RMQ问题与ST算法
RMQ(Range Minimum/Maximum Query)问题是求区间最值问题. 对于长度为 n 的数组 A,进行若干次查询,对于区间 [L,R] 返回数组A中下标在 [L,R] 中的最小(大) ...
- 51NOD1174 区间最大数 && RMQ问题(ST算法)
RMQ问题(区间最值问题Range Minimum/Maximum Query) ST算法 RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度 ...
- HDU 3183 A Magic Lamp(RMQ问题, ST算法)
原题目 A Magic Lamp Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU 3183 - A Magic Lamp - [RMQ][ST算法]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3183 Problem DescriptionKiki likes traveling. One day ...
- RMQ问题+ST算法
一.相关定义 RMQ问题 求给定区间的最值: 一般题目给定许多询问区间. 常见问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大 ...
- POJ 3264 Balanced Lineup RMQ ST算法
题意:有n头牛,编号从1到n,每头牛的身高已知.现有q次询问,每次询问给出a,b两个数.要求给出编号在a与b之间牛身高的最大值与最小值之差. 思路:标准的RMQ问题. RMQ问题是求给定区间内的最值问 ...
- HDU 5443 The Water Problem (ST算法)
题目链接:HDU 5443 Problem Description In Land waterless, water is a very limited resource. People always ...
随机推荐
- Streams and .NET
http://www.codeguru.com/csharp/csharp/cs_data/streaming/article.php/c4223/Streams-and-NET.htm In thi ...
- linux socket使用经验总结
1. scoket函数中PF_INET AF_INET区别 在UNIX系列中,PF_INET表示poxis, BSD系列用AF_INET 2. in_addr_t inet_addr(const ...
- Gradle在大型Java项目上的应用
在Java构建工具的世界里,先有了Ant,然后有了Maven.Maven的CoC[1].依赖管理以及项目构建规则重用性等特点,让Maven几乎成为Java构建工具的事实标准.然而,冗余的依赖管理配置. ...
- Codeforces Round #131 (Div. 2) : B
首先能被2,5整除的数结尾必须是0: 如果没有0肯定不行: 然后判断他们的和ans%3: 如果==0,直接从大到小输出就行: 如果==1,要么删除它们之间最小的那个%3==1的,要么删除两个小的并且% ...
- MyEclipse配置进行Hibernate逆映射
MyEclipse中配置MyEclipse Database Explorer 方法(以mysql 数据库为例) 前言: 之前看到同学转了一篇帖子,就是关于在MyEclipse中配置mysql的,今天 ...
- Android网络框架Volley(体验篇)
Volley是Google I/O 2013推出的网络通信库,在volley推出之前我们一般会选择比较成熟的第三方网络通信库,如: android-async-http retrofit okhttp ...
- Node.js权威指南 (3) - Node.js基础知识
3.1 Node.js中的控制台 / 19 3.1.1 console.log方法 / 19 3.1.2 console.error方法 / 20 3.1.3 console.dir方法 / 21 3 ...
- 用Delphi实现WinSocket高级应用
用Delphi实现WinSocket高级应用 默认分类 2009-12-19 16:48 阅读6 评论0 字号: 大大 中中 小小 Socket通信在Windows 中是排队的形式 ...
- 495. Kids and Prizes
http://acm.sgu.ru/problem.php?contest=0&problem=495 学习:当一条路走不通,换一种对象考虑,还有考虑对立面. 495. Kids and Pr ...
- maya绝招(41--60)
第41招 捕捉和旋转 从MAYA5开始,双击工具箱中的移动缩放旋转工具,马上就可以调出工具属性栏.以旋转为例,将Snap Rotate勾选,并设置Step Size数值,就可以旋转特定的数值了 第42 ...