• POJ


    这个题目是一个典型的RMQ问题,给定一个整数序列,1~N,然后进行Q次询问,每次给定两个整数A,B,(1<=A<=B<=N),求给定的范围内,最大和最小值之差。

    解法一:这个是最初的解法,时间上可能会超时,下面还有改进算法.4969ms

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #define INF 1000010
     4 #define max(a,b) ((a)>(b)?(a):(b))
     5 #define min(a,b) ((a)>(b)?(b):(a))
     6 
     7 typedef struct res
     8 {
     9     int mx,mi;
    10 } pair;
    11 
    12 typedef struct node
    13 {
    14     struct node *lc,*rc;
    15     int ld,rd;
    16     pair res;
    17 }  node;
    18 
    19 node *buildTree(int a,int b)
    20 {
    21     node*p=(node*)malloc(sizeof(node));
    22     p->ld=a;
    23     p->rd=b;
    24     p->res.mx=0;
    25     p->res.mi=INF;
    26     p->lc=p->rc=NULL;
    27     if(a==b)
    28         return p;
    29     p->lc=buildTree(a,(a+b)>>1);
    30     p->rc=buildTree(((a+b)>>1)+1,b);
    31     return p;
    32 }
    33 
    34 void insert(node*T,int pos,int key)
    35 {
    36     int mid=(T->rd+T->ld)>>1;
    37     if(T->rd==T->ld)
    38     {
    39         T->res.mx=T->res.mi=key;
    40         return;
    41     }
    42     if(pos<=mid)
    43         insert(T->lc,pos,key);
    44     else insert(T->rc,pos,key);
    45     T->res.mx=max(T->lc->res.mx,T->rc->res.mx);
    46     T->res.mi=min(T->lc->res.mi,T->rc->res.mi);
    47     return;
    48 }
    49 
    50 pair search(node*T,int a,int b)
    51 {
    52     pair  temp1,temp2,ans;
    53     int mid=(T->rd+T->ld)>>1;
    54 
    55     temp1.mx=temp2.mx=0;
    56     temp1.mi=temp2.mi=INF;
    57     if(a<=T->ld&&T->rd<=b)
    58         return T->res;
    59     if(a<=mid)
    60         temp1=search(T->lc,a,b);
    61     if(b>mid)
    62         temp2=search(T->rc,a,b);
    63     ans.mx=max(temp1.mx,temp2.mx);
    64     ans.mi=min(temp1.mi,temp2.mi);
    65     return ans;
    66 }
    67 
    68 int main(void)
    69 {
    70     int n,q,i,a,b;
    71     pair ans;
    72     scanf("%d%d",&n,&q);
    73     node *head=buildTree(1,n);
    74     for(i=1; i<=n; i++)
    75     {
    76         scanf("%d",&a);
    77         insert(head,i,a);
    78     }
    79     for(i=1; i<=q; i++)
    80     {
    81         scanf("%d%d",&a,&b);
    82         ans=search(head,a,b);
    83         printf("%d
    ",ans.mx-ans.mi);
    84     }
    85     return 0;
    86 }

    解法二:

    利用数组的形式:3704ms

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<string.h>
     4 #define N 1000010
     5 #define INF 1000010
     6 #define max(a,b) ((a)>(b)?(a):(b))
     7 #define min(a,b) ((a)>(b)?(b):(a))
     8 
     9 int l[N],r[N],i,n;
    10 typedef struct
    11 {
    12     int mx,mi;
    13 } pair;
    14 pair res[N];
    15 
    16 void BuildTree(int x,int y,int p)
    17 {
    18     l[p]=x;
    19     r[p]=y;
    20     if(x==y)
    21         return;
    22     BuildTree(x,(x+y)>>1,2*p);
    23     BuildTree(((x+y)>>1)+1,y,2*p+1);
    24 }
    25 
    26 void Insert(int num,int p)
    27 {
    28     int mid=(l[p]+r[p])>>1;
    29     res[p].mx=max(res[p].mx,num);
    30     res[p].mi=min(res[p].mi,num);
    31     if(l[p]==r[p])
    32         return;
    33     if(i<=mid)
    34         Insert(num,2*p);
    35     else Insert(num,2*p+1);
    36 }
    37 
    38 pair search(int x,int y,int p)
    39 {
    40     pair a1,a2,ans;
    41     a1.mx=a2.mx=0;
    42     a1.mi=a2.mi=INF;
    43     int mid=(l[p]+r[p])>>1;
    44     if(x<=l[p]&&y>=r[p])
    45         return res[p];
    46     if(x<=mid)
    47     a1=search(x,y,2*p);
    48     if(y>mid)
    49     a2=search(x,y,2*p+1);
    50     ans.mx=max(a1.mx,a2.mx);
    51     ans.mi=min(a1.mi,a2.mi);
    52     return ans;
    53 }
    54 
    55 int main(void)
    56 {
    57     int q,j,x,y;
    58     pair ans;
    59     memset(res,0,sizeof(res));
    60     scanf("%d%d",&n,&q);
    61     BuildTree(1,n,1);
    62     for(i=0; i<N; i++)
    63         res[i].mi=INF;
    64     for(i=1; i<=n; i++)
    65     {
    66         scanf("%d",&j);
    67         Insert(j,1);
    68     }
    69 
    70     for(i=0; i<q; i++)
    71     {
    72         scanf("%d%d",&x,&y);
    73         ans=search(x,y,1);
    74         printf("%d
    ",ans.mx-ans.mi);
    75     }
    76     return 0;
    77 }

     解法三:

    这是利用别人的算法改进而来,所以有时候多借鉴别人的代码,并且可以和自己的想法结合起来,效果还不错.

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<stdlib.h>
     4 #define N 50010
     5 #define INF 1000010
     6 #define max(a,b) ((a)>(b)?(a):(b))
     7 #define min(a,b) ((a)>(b)?(b):(a))
     8 
     9 typedef struct
    10 {
    11     int l,r;
    12     int mx,mi;
    13 } pair;
    14 pair temp[N*3];
    15 int Max,Min;
    16 
    17 void BuildTree(int x,int y,int p)
    18 {
    19     temp[p].l=x;
    20     temp[p].r=y;
    21     temp[p].mx=0;
    22     temp[p].mi=INF;
    23     if(x==y)
    24         return;
    25     int mid=(x+y)/2;
    26     BuildTree(x,mid,p*2);
    27     BuildTree(mid+1,y,2*p+1);
    28 }
    29 
    30 void Insert(int v,int num,int p)
    31 {
    32     if(temp[v].l==temp[v].r)
    33     {
    34         temp[v].mx=temp[v].mi=num;
    35         return ;
    36     }
    37     int mid=(temp[v].r+temp[v].l)/2;
    38     if(p<=mid)
    39     {
    40         Insert(2*v,num,p);
    41         temp[v].mx=max(temp[v].mx,temp[2*v].mx);
    42         temp[v].mi=min(temp[v].mi,temp[2*v].mi);
    43     }
    44     else
    45     {
    46         Insert(2*v+1,num,p);
    47         temp[v].mx=max(temp[v].mx,temp[2*v+1].mx);
    48         temp[v].mi=min(temp[v].mi,temp[2*v+1].mi);
    49     }
    50 }
    51 
    52 void search(int x,int y,int p)
    53 {
    54     if(temp[p].l==x&&temp[p].r==y)
    55     {
    56         Max=max(Max,temp[p].mx);
    57         Min=min(Min,temp[p].mi);
    58         return;
    59     }
    60     int mid=(temp[p].l+temp[p].r)/2;
    61     if(x>mid)
    62     {
    63         search(x,y,2*p+1);
    64     }
    65     else if(y<=mid)
    66     {
    67         search(x,y,2*p);
    68     }
    69     else
    70     {
    71         search(x,mid,2*p);
    72         search(mid+1,y,2*p+1);
    73     }
    74     return;
    75 }
    76 
    77 int main(void)
    78 {
    79     int n,q,i,x,y;
    80     scanf("%d%d",&n,&q);
    81     BuildTree(1,n,1);
    82     for(i=1;i<=n;i++)
    83     {
    84         scanf("%d",&x);
    85         Insert(1,x,i);
    86     }
    87     for(i=0;i<q;i++)
    88     {
    89         scanf("%d%d",&x,&y);
    90         Max=0;
    91         Min=INF;
    92         search(x,y,1);
    93         printf("%d
    ",Max-Min);
    94     }
    95     return 0;
    96 }
  • 相关阅读:
    PLSQL连接64位oracle,导入导出错误解决办法
    VS2008或者VS2010工具栏,标准里面的 在浏览器中浏览按钮不见了
    jquery radio取值,checkbox取值,select取值 及选中
    Waiting for HOME (‘android.process.acore’) to be launched…解决办法
    GetTickCount() 函数的作用和用法
    MFC ado连接access数据库
    VC切分窗口和多视图
    C++容器——插入与清除
    VC中在对话框上显示图片
    error LNK2005 已经在***.obj中定义
  • 原文地址:https://www.cnblogs.com/rootial/p/3204185.html
Copyright © 2020-2023  润新知