[关闭]
@zhshh 2018-07-22T12:32:30.000000Z 字数 1002 阅读 728

RMQ与st表

@zhshh OI cpp 数据结构


模板题
P3865 【模板】ST表

代码

实质也是DP,利用倍增获取从i开始长度为的区间内的最大值。
这样对于任意区间都有,令则有这样在区间完全覆盖了这个区域(中间可能有重叠)

  1. #include <iostream>
  2. #include <cmath>
  3. #include <cstdio>
  4. using namespace std;
  5. int dp[100100][20];
  6. int a[100100];
  7. int lg[100100];
  8. int n,m;
  9. void st(){
  10. for(int i=1;i<=n;i++){
  11. dp[i][0]=a[i];
  12. }
  13. for(int j=1;(1<<j)<=n;j++){
  14. for(int i=1;i+(1<<j)-1<=n;i++){
  15. dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
  16. }
  17. }
  18. // 方法2
  19. // int k=0;
  20. // for(int i=1;i<=n;i++){
  21. // if(i<=(1<<(k))){
  22. // lg[i]=k;
  23. // }else{
  24. // k++;
  25. // lg[i]=k;
  26. // }
  27. // }
  28. }
  29. int RMQ(int l,int r){
  30. int k=0;
  31. // 方法2
  32. // k=lg[r-l+1]-1;
  33. // 方法3
  34. // while((1<<(k+1))<=r-l+1){
  35. // k++;
  36. // }
  37. // 方法1
  38. k=(double)log(r-l+1)/log(2);
  39. return max(dp[l][k],dp[r-(1<<k)+1][k]);
  40. }
  41. void init(){
  42. cin>>n>>m;
  43. for(int i=1;i<=n;i++){
  44. scanf("%d",&a[i]);
  45. }
  46. }
  47. int main(){
  48. init();
  49. st();
  50. // cout<<RMQ(1,5);
  51. int q,w;
  52. for(int i=1;i<=m;i++){
  53. scanf("%d%d",&q,&w);
  54. printf("%d\n",RMQ(q,w));
  55. }
  56. }

计算log的方法可以提前用O(n)的预处理(方法2)或者每次lgn的计算(常数很小,基本上可以忽略)或者不知道常数的。。log算法
反正从代码上来看时间,log预处理计算
分别是1112ms 1224ms 1648ms
洛谷评测

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注