bon

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  46 Posts :: 0 Stories :: 12 Comments :: 0 Trackbacks

常用链接

留言簿(2)

我参与的团队

搜索

  •  

最新评论

阅读排行榜

评论排行榜

PKU 3264
经典RMQ。给定一个序列,要求找出给定区间 [l,r] 中的最大值与最小值之差。
这个算法是最近刚接触的,最初的感觉就是动态规划能用到这个地步,经典啊!
 1 #include <iostream>
 2 #include <math.h>
 3 
 4 #define max(a,b) ((a>b)?a:b)
 5 #define min(a,b) (a<b?a:b)
 6 
 7 using namespace std;
 8 
 9 const int maxn=50001;
10 int h[maxn];
11 int mx[maxn][16],mn[maxn][16];
12 int n,q;
13 
14 void rmq_init()
15 {
16     int i,j;
17     for(j=1;j<=n;j++) mx[j][0]=mn[j][0]=h[j];
18     int m=floor(log((double)n)/log(2.0));
19     for(i=1;i<=m;i++){
20         for(j=n;j>0;j--){
21             mx[j][i]=mx[j][i-1];
22             if(j+(1<<(i-1))<=n) mx[j][i]=max(mx[j][i],mx[j+(1<<(i-1))][i-1]);
23         }
24     }
25     for(i=1;i<=m;i++){
26         for(j=n;j>0;j--){
27             mn[j][i]=mn[j][i-1];
28             if(j+(1<<(i-1))<=n) mn[j][i]=min(mn[j][i],mn[j+(1<<(i-1))][i-1]);
29         }
30     }
31 }
32 
33 int rmq(int l,int r)
34 {
35     int m=floor(log((double)(r-l+1))/log(2.0));
36     int a=max(mx[l][m],mx[r-(1<<m)+1][m]);
37     int b=min(mn[l][m],mn[r-(1<<m)+1][m]);
38     return a-b;
39     
40 }
41 
42 int main()
43 {
44     int i,l,r;
45     scanf("%d%d",&n,&q);
46     for(i=1;i<=n;i++) scanf("%d",&h[i]);
47     rmq_init();
48     for(i=0;i<q;i++){
49         scanf("%d%d",&l,&r);
50         printf("%d\n",rmq(l,r));
51     }
52     return 1;
53 }
54 
posted on 2008-03-18 22:20 bon 阅读(435) 评论(0)  编辑 收藏 引用 所属分类: Programming Contest

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


Google PageRank 
Checker - Page Rank Calculator