这个题目是一个典型的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=;
  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)>>);
  30. p->rc=buildTree(((a+b)>>)+,b);
  31. return p;
  32. }
  33.  
  34. void insert(node*T,int pos,int key)
  35. {
  36. int mid=(T->rd+T->ld)>>;
  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)>>;
  54.  
  55. temp1.mx=temp2.mx=;
  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(,n);
  74. for(i=; i<=n; i++)
  75. {
  76. scanf("%d",&a);
  77. insert(head,i,a);
  78. }
  79. for(i=; i<=q; i++)
  80. {
  81. scanf("%d%d",&a,&b);
  82. ans=search(head,a,b);
  83. printf("%d\n",ans.mx-ans.mi);
  84. }
  85. return ;
  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)>>,*p);
  23. BuildTree(((x+y)>>)+,y,*p+);
  24. }
  25.  
  26. void Insert(int num,int p)
  27. {
  28. int mid=(l[p]+r[p])>>;
  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,*p);
  35. else Insert(num,*p+);
  36. }
  37.  
  38. pair search(int x,int y,int p)
  39. {
  40. pair a1,a2,ans;
  41. a1.mx=a2.mx=;
  42. a1.mi=a2.mi=INF;
  43. int mid=(l[p]+r[p])>>;
  44. if(x<=l[p]&&y>=r[p])
  45. return res[p];
  46. if(x<=mid)
  47. a1=search(x,y,*p);
  48. if(y>mid)
  49. a2=search(x,y,*p+);
  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,,sizeof(res));
  60. scanf("%d%d",&n,&q);
  61. BuildTree(,n,);
  62. for(i=; i<N; i++)
  63. res[i].mi=INF;
  64. for(i=; i<=n; i++)
  65. {
  66. scanf("%d",&j);
  67. Insert(j,);
  68. }
  69.  
  70. for(i=; i<q; i++)
  71. {
  72. scanf("%d%d",&x,&y);
  73. ans=search(x,y,);
  74. printf("%d\n",ans.mx-ans.mi);
  75. }
  76. return ;
  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*];
  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=;
  22. temp[p].mi=INF;
  23. if(x==y)
  24. return;
  25. int mid=(x+y)/;
  26. BuildTree(x,mid,p*);
  27. BuildTree(mid+,y,*p+);
  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)/;
  38. if(p<=mid)
  39. {
  40. Insert(*v,num,p);
  41. temp[v].mx=max(temp[v].mx,temp[*v].mx);
  42. temp[v].mi=min(temp[v].mi,temp[*v].mi);
  43. }
  44. else
  45. {
  46. Insert(*v+,num,p);
  47. temp[v].mx=max(temp[v].mx,temp[*v+].mx);
  48. temp[v].mi=min(temp[v].mi,temp[*v+].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)/;
  61. if(x>mid)
  62. {
  63. search(x,y,*p+);
  64. }
  65. else if(y<=mid)
  66. {
  67. search(x,y,*p);
  68. }
  69. else
  70. {
  71. search(x,mid,*p);
  72. search(mid+,y,*p+);
  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(,n,);
  82. for(i=;i<=n;i++)
  83. {
  84. scanf("%d",&x);
  85. Insert(,x,i);
  86. }
  87. for(i=;i<q;i++)
  88. {
  89. scanf("%d%d",&x,&y);
  90. Max=;
  91. Min=INF;
  92. search(x,y,);
  93. printf("%d\n",Max-Min);
  94. }
  95. return ;
  96. }

POJ - 3264 Balanced Lineup 线段树解RMQ的更多相关文章

  1. poj 3264 Balanced Lineup(线段树、RMQ)

    题目链接: http://poj.org/problem?id=3264 思路分析: 典型的区间统计问题,要求求出某段区间中的极值,可以使用线段树求解. 在线段树结点中存储区间中的最小值与最大值:查询 ...

  2. POJ 3264 Balanced Lineup 线段树RMQ

    http://poj.org/problem?id=3264 题目大意: 给定N个数,还有Q个询问,求每个询问中给定的区间[a,b]中最大值和最小值之差. 思路: 依旧是线段树水题~ #include ...

  3. [POJ] 3264 Balanced Lineup [线段树]

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 34306   Accepted: 16137 ...

  4. POJ 3264 Balanced Lineup 线段树 第三题

    Balanced Lineup Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line ...

  5. POJ 3264 Balanced Lineup (线段树)

    Balanced Lineup For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the s ...

  6. 【POJ】3264 Balanced Lineup ——线段树 区间最值

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 34140   Accepted: 16044 ...

  7. Poj 3264 Balanced Lineup RMQ模板

    题目链接: Poj 3264 Balanced Lineup 题目描述: 给出一个n个数的序列,有q个查询,每次查询区间[l, r]内的最大值与最小值的绝对值. 解题思路: 很模板的RMQ模板题,在这 ...

  8. POJ 3264 Balanced Lineup -- RMQ或线段树

    一段区间的最值问题,用线段树或RMQ皆可.两种代码都贴上:又是空间换时间.. RMQ 解法:(8168KB 1625ms) #include <iostream> #include < ...

  9. POJ 3264 Balanced Lineup【线段树区间查询求最大值和最小值】

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 53703   Accepted: 25237 ...

随机推荐

  1. GridView中使用如下button OnClientClick代码会出现解析错误

    在GridView中使用如下代码会出现解析错误: <asp:LinkButton ID="DeleteButton" runat="server" Cau ...

  2. 100个iOS开发面试题汇总-王刚韧的技术博客

    100个iOS开发面试题汇总 关于iOS开发面试,不管对于招聘和应聘来说,面试都是很重要的一个环节,特别对于开发者来说,面试中的技术问题环节不仅是企业对应聘者技能和积累的考察,也是一个开发者自我检验的 ...

  3. javascript 基础3第13节

    <html> <head> <title>javascript基础</title> </head> <body> 1.流程控制 ...

  4. Java实战之01Struts2-02配置文件

    三.Struts2的配置文件 1.加载时机: 当应用被tomcat加载的时候,struts2的配置文件就已经被加载过了. 2.加载顺序 顺序 配置文件名 所在位置 说明 1 default.prope ...

  5. bzoj1697:[Usaco2007 Feb]Cow Sorting牛排序 & bzoj1119:[POI2009]SLO

    思路:以bzoj1119为例,题目已经给出了置换,而每一次交换的代价是交换二者的权值之和,而置换一定是会产生一些环的,这样就可以只用环内某一个元素去置换而使得其余所有元素均在正确的位置上,显然要选择环 ...

  6. Effective C++ 学习总结

    摒弃C的做法采用C++的实现方式 以const和inline代替define 以iostream流代替stdio 以new和delete代替 C++风格注释 内存管理 new和delete, new[ ...

  7. ASP.NET全局文件与防盗链

    添加Web→全局应用程序类,注 文件名不要改 Global.asax 全局文件是对Web应用声明周期的一个事件响应的地方,将Web应用启动时初始化的一些代码写到 Application_Start中, ...

  8. 分享一下个人的Vim配置文件

    强烈拥护开源精神,高举开源大旗,今天我就分享下我自己结合网上还有自己实际使用配的vimrc,可以给各位参考下,不要见笑哈,具体说明我在rc里写的也很详细,可以具体看下,也希望可以借这个机会能多认识认识 ...

  9. 关于Linux内核学习的误区以及相关书籍介绍

    http://www.hzlitai.com.cn/article/ARM9-article/system/1605.html 写给Linux内核新手-关于Linux内核学习的误区 先说句正经的:其实 ...

  10. VI一个终端编辑多个文件的命令

      可分两种情况: 在不同窗口中打开多个文件:   如果已经打开一个了一个文件, 则在vi的命令输入状态下输入 :sp 另外一个文件的路径及文件名, 如此就可以在一个窗口打开多个文件了.   可以使用 ...