RMQ问题各种模板哈(对于我这样的大水B来说,模板多好~~~)


 1  #include <iostream>
 2  #include <math.h>
 3  #include <cstdio>
 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   int main()
42    {
43        freopen("input.txt","r",stdin);
44       int i,l,r;
45       int num;
46       scanf("%d",&num);
47       for(int jj=1;jj<=num;jj++){
48       scanf("%d%d",&n,&q);
49       for(i=1;i<=n;i++) scanf("%d",&h[i]);
50       rmq_init();
51       printf("Test case #%d:\n",jj);
52        for(i=0;i<q;i++){
53           scanf("%d%d",&l,&r);
54           printf("%d\n",rmq(l,r));
55       }
56 
57     }
58     return 0;
59    }
60  用这个了
61 思路比较清晰  速度也不慢

 

  1 template < class Type>
  2 class rmq_st{
  3 private:
  4       Type* body;   
  5       int** mi;      
  6       int size;     
  7       int len;     
  8  
  9       int dint(double a){       
 10           int buf=a;   
 11           if(buf>a){
 12               --buf;
 13           }
 14           return buf;
 15       }
 16  
 17       int mlen(int l,int r){
 18           double buf=log((double)(r-l+1))/log((double)2);  
 19           return dint(buf)
 20       }   
 21       bool (*less)(Type& t1,Type& t2);
 22  
 23 public:
 24  
 25 
 26      //构造函数 : (待求数组,大小,小于函数)      
 27       rmq_st(Type* con,int s,bool (*lessthan)(Type& t1,Type& t2));
 28            
 29       ~rmq_st();//解构
 30      
 31       Type get_body(int p);//返回指定索引的元素
 32  
 33       int query_index(int l,int r);//返回指定区间最小值的元素索引
 34  
 35       Type query(int l,int r);//返回指定区间的最小元素
 36 };
 37  
 38 template < class Type> 
 39 rmq_st< Type>::rmq_st(Type* con,int s,bool (*lessthan)(Type& t1,Type& t2)){
 40       less=lessthan;
 41       body=con;
 42       size=s;
 43       len=mlen(0,s-1)+1;
 44       mi=new int*[size];
 45       int i,j;
 46       for(i=0;i< size;++i){
 47           mi[i]=new int[len];
 48       }
 49       int bound;  
 50       int a,b;    
 51       for(i=0;i< size;++i){   
 52           mi[i][0]=i; 
 53       } 
 54       for(i=1;i< len;++i){     
 55           bound=n-(1<< i)+1;      
 56           for(j=0;j< bound;++j){      
 57               a=mi[j][i-1];       
 58               b=mi[j+(1<< (i-1))][i-1];    
 59               mi[j][i]=less(body[a],body[b])?a:b;
 60           } 
 61       }
 62 }
 63  
 64 template < class Type> 
 65 rmq_st< Type>::~rmq_st(){
 66       int i;
 67       for(i=0;i< size;++i){
 68           delete[] mi[i];
 69       }    
 70       delete[] mi;
 71 }
 72  
 73 template < class Type> 
 74 Type rmq_st< Type>::get_body(int p){
 75       return body[p];
 76 }
 77  
 78 template < class Type> 
 79 int rmq_st< Type>::query_index(int l,int r){
 80       int length=mlen(l,r);        
 81       int a=mi[l][length];
 82       int b=mi[r-(1<< length)+1][length];
 83       return less(body[a],body[b])?a:b;
 84 }
 85  
 86 template < class Type> 
 87 Type rmq_st< Type>::query(int l,int r){
 88       int length=mlen(l,r);
 89       int a=mi[l][length];
 90       int b=mi[r-(1<< length)+1][length];
 91       return less(body[a],body[b])?body[a]:body[b];
 92 }
 93  
 94 /*----------------Example : POJ 3264    Memory:7708K   Time:3230MS-----------------*/
 95  
 96 int cow[50001];
 97 int n,q;
 98  
 99 bool cmpmin(int& t1,int& t2){
100       return t1< t2;
101 }
102  
103 bool cmpmax(int& t1,int& t2){
104       return t1>t2;
105 }
106  
107 int main()
108 {
109 //    freopen("1.in","r",stdin);
110       scanf("%d %d",&n,&q);
111       int i;    
112       for(i=0;i< n;++i){
113           scanf("%d",&cow[i]);
114       }
115       rmq_st< int> minst(cow,n,cmpmin);
116       rmq_st< int> maxst(cow,n,cmpmax);
117       int a,b;
118       for(i=0;i< q;++i){
119           scanf("%d %d",&a,&b);
120           --a;
121           --b;
122           printf("%d\n",maxst.query(a,b)-minst.query(a,b));
123       }      
124       return 0;
125 }



342ms.................

 

posted @ 2013-05-23 08:15  闭关修炼的小孩纸  阅读(183)  评论(0编辑  收藏  举报