POJ3264 RMQ问题 裸 线段树 OR ST算法
2016-05-05 00:15
435 查看
0)解决RMQ问题。此处用线段树或ST算法。
线段树O(logn)的复杂度一般可以AC,ST算法是O(nlogn)预处理和O(1)的查询速度,一般情况下线段树快一些但如果查询量非常大,ST算法优于线段树。
1)注意,NodeNum一般开3倍或4倍。
如果对输出格式要求不是很多,那么用cout比printf快哦。
线段树,O(logn)复杂度,2000ms(把最后cout改为printf就会3000ms多哦)
ST算法(动态规划),O(nlogn)预处理和O(1)的查询,3400ms(把printf改为cout3200ms,这个差距不大,但这个现象却恰恰诠释了ST算法是O(1)的查询速度,所以对于查询时输出用cout还是printf的优化效果不如O(logn)的线段树对查询输出进行优化的效果更明显!)
2)
Description
For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer John decides to organize a game of Ultimate Frisbee with some of the cows. To keep things simple, he will take a contiguous range
of cows from the milking lineup to play the game. However, for all the cows to have fun they should not differ too much in height.
Farmer John has made a list of Q (1 ≤ Q ≤ 200,000) potential groups of cows and their heights (1 ≤height ≤ 1,000,000). For each group, he wants your help to determine the difference in height between the shortest and the tallest
cow in the group.
Input
Line 1: Two space-separated integers, N andQ.
Lines 2.. N+1: Line i+1 contains a single integer that is the height of cowi
Lines N+2.. N+ Q+1: Two integers A and B (1 ≤A ≤B ≤N), representing the range of cows fromA toB inclusive.
Output
Lines 1.. Q: Each line contains a single integer that is a response to a reply and indicates the difference in height between the tallest and shortest cow in the range.
Sample Input
Sample Output
线段树O(logn)的复杂度一般可以AC,ST算法是O(nlogn)预处理和O(1)的查询速度,一般情况下线段树快一些但如果查询量非常大,ST算法优于线段树。
1)注意,NodeNum一般开3倍或4倍。
如果对输出格式要求不是很多,那么用cout比printf快哦。
线段树,O(logn)复杂度,2000ms(把最后cout改为printf就会3000ms多哦)
#include <iostream> #include <stdio.h> #include <algorithm> using namespace std; const int INF=0x3f3f3f3f; const int NodeNum=200005*3; const int queNum=200010; int a[NodeNum]; int nmin; int nmax; struct Node{ int l; int r; int minn; int maxx; }node[NodeNum]; void Build(int id,int l,int r){ node[id].l=l; node[id].r=r; if(l==r){ node[id].maxx=a[l]; node[id].minn=a[l]; return ; } int mid=(l+r)>>1; Build(id<<1,l,mid); Build((id<<1)+1,mid+1,r); node[id].maxx=max(node[id<<1].maxx,node[(id<<1)+1].maxx);//(id<<1)+1可以换成id<<1|1,意思是如果id<<1是偶数那么就+1,否则就不变,因为id<<1所以一定是偶数 node[id].minn=min(node[id<<1].minn,node[(id<<1)+1].minn);//因为优先级的原因,所以(id<<1)+1中的括号是有必要的 } void Query(int id,int l,int r){ if(node[id].maxx<=nmax&&nmin<=node[id].minn){ return ; } if(node[id].l==l&&r==node[id].r){ nmin=min(nmin,node[id].minn); nmax=max(nmax,node[id].maxx); return; } int mid=(node[id].l+node[id].r)>>1; if(r<=mid){ Query(id<<1,l,r); } else if(mid+1<=l){ Query((id<<1)+1,l,r); } else { Query(id<<1,l,mid); Query((id<<1)+1,mid+1,r); } } int main(){ int n,q; while(~scanf("%d %d",&n,&q)){ for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } Build(1,1,n); for(int i=1;i<=q;i++){ int l,r; nmin=INF; nmax=-INF; scanf("%d %d",&l,&r); Query(1,l,r); cout<<nmax-nmin<<endl; //printf("%d\n",nmax-nmin); } } return 0; }
ST算法(动态规划),O(nlogn)预处理和O(1)的查询,3400ms(把printf改为cout3200ms,这个差距不大,但这个现象却恰恰诠释了ST算法是O(1)的查询速度,所以对于查询时输出用cout还是printf的优化效果不如O(logn)的线段树对查询输出进行优化的效果更明显!)
//RMQ ---RMQ简介 :http://blog.csdn.net/niushuai666/article/details/6624672 #include <iostream> #include <string.h> #include <stdio.h> #include <math.h> using namespace std; const int maxn=50010; //int cows[maxn]; int heigh[maxn][20]; int low[maxn][20]; void Rmq(int num){ //预处理,递推并记忆,利用二进制,存储每个数起(包括它本身),往后2^0 2^1 2^2......2^k个数来覆盖所有区间。 //第i个数开始,往后j个数,把这部分平分成两半处理,直到每个数都是往后2^0个(本身),也就是初始化的状态。 for(int j=1;j<20;j++){ for(int i=1;i<=num;i++){ if(i+(1<<j)-1<=num){ heigh[i][j]=max(heigh[i][j-1],heigh[i+(1<<(j-1))][j-1]); low[i][j]=min(low[i][j-1],low[i+(1<<(j-1))][j-1]); } } } } int main() { int n,q; cin>>n>>q; //先进行初始化,将所有一个数的(每个数本身)进行赋值。 for(int i=1;i<=n;i++){ scanf("%d",&heigh[i][0]); low[i][0]=heigh[i][0]; } Rmq(n); int star,endd; for(int l=1;l<=q;l++){ scanf("%d%d",&star,&endd); //查询的区间,可以分成两个有交集的区间,分别求最大或最小,然后再比较一次得到最值,因此可以覆盖所有区间! if(star>endd){ swap(star,endd); } int k=(int)(log(endd-star+1.0)/log(2.0));//+1.0变成floor printf("%d\n",max(heigh[star][k],heigh[endd-(1<<k)+1][k])-min(low[star][k],low[endd-(1<<k)+1][k]));//int res=max(heigh[star][k],heigh[endd-(1<<k)+1][k])-min(low[star][k],low[endd-(1<<k)+1][k]); cout<<res<<endl; } }
2)
Description
For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer John decides to organize a game of Ultimate Frisbee with some of the cows. To keep things simple, he will take a contiguous range
of cows from the milking lineup to play the game. However, for all the cows to have fun they should not differ too much in height.
Farmer John has made a list of Q (1 ≤ Q ≤ 200,000) potential groups of cows and their heights (1 ≤height ≤ 1,000,000). For each group, he wants your help to determine the difference in height between the shortest and the tallest
cow in the group.
Input
Line 1: Two space-separated integers, N andQ.
Lines 2.. N+1: Line i+1 contains a single integer that is the height of cowi
Lines N+2.. N+ Q+1: Two integers A and B (1 ≤A ≤B ≤N), representing the range of cows fromA toB inclusive.
Output
Lines 1.. Q: Each line contains a single integer that is a response to a reply and indicates the difference in height between the tallest and shortest cow in the range.
Sample Input
6 3 1 7 3 4 2 5 1 5 4 6 2 2
Sample Output
6 3 0
相关文章推荐
- gi本地、远程仓库的创建
- Postgresql 9 高可用性 手册
- SDAU dp专题 1010
- javascript闭包详解及常见陷进
- 第六节 事务XML方式[声明方式]
- sublime text3 如何卸载package control
- Provisioning Services 7.8 入门系列教程之五 使用Provisioning Services控制台
- 畅通工程续 (dijkstra)
- 位图bitmap算法(java)
- Mac下java环境变量配置
- 如果有人问你数据库的原理,叫他看这篇文章(上)
- linux 策略路由
- web前端学习笔记:文本属性
- 《CSS3实战》笔记--渐变设计(二)
- Android Context完全解析,你所不知道的Context的各种细节
- NSString新用法 字符串_过滤处理NSCharacterSet 与invertedSet
- webkit架构和模块
- SDAU dp专题 1009
- 排序方法
- 用Bundle 传数据