zoukankan      html  css  js  c++  java
  • RMQ,ST表,dp

    RMQ算法,

    st表,dp思想

    直接上代码吧,

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <string>
     4 #include <bits/stdc++.h>
     5 
     6 using namespace std;
     7 typedef long long ll;
     8 typedef unsigned long long ull;
     9 
    10 #define MAXN 100001
    11 int stmax[MAXN][21];
    12 int stmin[MAXN][21];
    13 int a[MAXN];
    14 int n,q;
    15 
    16 void rmq(int n) {
    17     for (int j=1; j<20; j++) {
    18         for (int i=1; i<=n; i++) {
    19             if (i+(1<<j)-1<=n) {
    20                 stmax[i][j]=max(stmax[i][j-1],stmax[i+(1<<(j-1))][j-1]);
    21                 stmin[i][j]=min(stmin[i][j-1],stmin[i+(1<<(j-1))][j-1]);
    22             }
    23         }
    24     }
    25 }
    26 int ask(int l,int r) {
    27     int k=log(r-l+1)/log(2);
    28     int maxans=max(stmax[l][k],stmax[r-(1<<k)+1][k]);
    29     int minans=min(stmin[l][k],stmin[r-(1<<k)+1][k]);
    30     cout<<maxans<<" "<<minans<<endl; 
    31 }
    32 
    33 int main () {
    34     cin>>n>>q;
    35     for (int i=1;i<=n;i++) {
    36         cin>>a[i];
    37         stmax[i][0]=a[i];
    38         stmin[i][0]=a[i];
    39     }
    40     rmq(n);
    41     for (int i=1,l,r;i<=q;i++) {
    42         cin>>l>>r;
    43         ask(l,r);
    44     }
    45 
    46     return 0;
    47 }

    RMQ还有扩展应用,

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    #include <cassert>
    
    using namespace std;
    typedef long long LL;
    LL mod = 1e9+7;
    LL cnt;
    int s[100005],n,q;
    int sta[100005][20],sto[100005][20];
    int aska(int l,int r) {
        int L=r-l+1;
        int t = log2(L);
        return sta[l][t] & sta[r-(1<<t)+1][t];
        //对应区间最小
    }
    int asko(int l,int r) {
        int L=r-l+1;
        int t = log2(L);
        return sto[l][t] | sto[r-(1<<t)+1][t];
        //对应区间最大
    }
    int main() {
        scanf("%d%d",&n,&q);
        for(int i=1; i<=n; i++) {
            scanf("%d",&s[i]);
            sta[i][0]=sto[i][0]=s[i];
        }
        for(int j=1; j<20; j++) {
            for(int i=1; i<=n; i++) {
                if(i+(1<<j) -1 <=n) {
                    sta[i][j] = sta[i][j-1] & sta[i+(1<<(j-1))][j-1];
                    sto[i][j] = sto[i][j-1] | sto[i+(1<<(j-1))][j-1];
                }
            }
        }
    
        for(int i=1,l,r; i<=q; i++) {
            scanf("%d%d",&l,&r);
            cout<<aska(l,r)<<" "<<asko(l,r)<<endl;
        }
    
    
        return 0;
    }

    扩展之后RMQ可以求一个序列一段区间连续按位与,按位或的值

    按位与对应区间最小值

    按位或对应区间最大值

  • 相关阅读:
    stm32启动代码分析
    STM32固件库详解
    ARM GCC CodeSourcery EABI下载地址
    Linux/redhat 基本网络配置
    侧边栏导航
    div滚动,页面不滚动
    自定义滚动条样式
    placeholder自定义CSS
    浏览器判断
    初始化页面垂直居中
  • 原文地址:https://www.cnblogs.com/codemaker-li/p/9799354.html
Copyright © 2011-2022 走看看