RMQ的妙用、

刚学了RMQ算法。

做pku 2201 的时候。刚开始根本没啥好的算法。按照一般的思路走下来肯定是超时。

后来看了讨论,用不熟练的RMQ写了个。(搞惨了,这个程序整了我一整天)

#include<algorithm>
#include<cmath>
#include<stdlib.h>
#include <algorithm>
using namespace std;
#define MAX 50005
struct Node{
       int parent;
       int left;
       int right;  
       int id;
       int key;
       int akey;   
};
Node tree[MAX];
int n,f[MAX][16];
bool cmpbykey(Node n1,Node n2){
     return (n1.key<n2.key);
}

bool cmpbyid(Node n1,Node n2){
     return (n1.id<n2.id);
}
void RMQ(){
     sort(tree+1,tree+n+1,cmpbykey);
     for(int i=1;i<=n;i++){
         f[i][0]=i;                
     }    
     for(int j=1;j<=log((double)(n))/log(2.0);j++)
     for(int i=1;(i+(1<<j)-1)<=n;i++){
             f[i][j]=f[i][j-1];
             if(tree[f[i+(1<<(j-1))][j-1]].akey<tree[f[i][j]].akey){
                    f[i][j]=f[i+(1<<(j-1))][j-1];                                                    
             }
     }
     /*for(int j=0;j<=log((double)(n-1))/log(2.0);j++)
     for(int i=1;i+(1<<j)-1<=n;i++){
        printf("%d",f[i][j]);
       
        system("pause");
     }*/
    
}

int Min_setbyRmq(int left,int right){
                 int m;
                 m=(log((double)(right-left+1))/log(2.0));
                 if(tree[f[left][m]].akey<tree[f[right-(1<<(m))+1][m]].akey)
                 return f[left][m];
                 else return f[right-(1<<m)+1][m];
                              
}
bool maketree(int left,int right){
     if(left==right) {
       tree[left].left=0;
       tree[left].right=0;             
       return true;
     }
     int root,rootleft,rootright;
     root=Min_setbyRmq(left,right);
   
     if(root!=left){
         rootleft=Min_setbyRmq(left,root-1);
        
     }
     if(root!=right){
          rootright=Min_setbyRmq(root+1,right);
     }
     bool check1=true,check2=true;
     if(root!=left&&tree[root].key>tree[rootleft].key){
              tree[root].left=tree[rootleft].id;
              tree[rootleft].parent=tree[root].id;
              check1=maketree(left,root-1);
     }
     if(root!=right&&tree[root].key<tree[rootright].key){
              tree[root].right=tree[rootright].id;
              tree[rootright].parent=tree[root].id;
              check2=maketree(root+1,right); 
     }
     return (check1&&check2);
}
int main(){
        int i,t;
        scanf("%d",&n);
       
        for(i=1;i<=n;i++){
            scanf("%d%d",&tree[i].key,&tree[i].akey);   
            tree[i].id=i;         
        }
        RMQ();
        if(maketree(1,n)){
        /*  for(i=1;i<=n;i++){
                           
            printf("%d %d %d\n",tree[i].parent,tree[i].left,tree[i].right);
            system("pause");
        }*/
        printf("YES\n");
        sort(tree+1,tree+n+1,cmpbyid);
        for(i=1;i<=n;i++){
            printf("%d %d %d\n",tree[i].parent,tree[i].left,tree[i].right);
            system("pause");
        }
      }
      else printf("NO\n");      
}
       

//主要是调试的时候,整死就是过不去。

//虽然不是完全独立坐下来的。不过还是感到很高兴、    

posted on 2009-08-15 17:27 昨日重现 阅读(100) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。
网站导航:

<2009年8月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
303112345

导航

统计

常用链接

留言簿(1)

随笔档案

相册

搜索

最新评论

阅读排行榜

评论排行榜