ST表:

  • 空间复杂度:O(nlogn),单词询问O(1),预处理时间复杂度O(nlogn);
  • d【i】【j】表示左端点i,长度为2^j的区间的最值问题 他管辖了【i】【i+2^j-1】这个区间
  • d[5][3]=MIN(d[5][2],d[9][2])
  • min(5,12)=min(5, 8)和min(9,12)取min
  • 询问[5,10] 区间长度为6,log6为log[6>>1]+1=2;
  • 则[5,10]=min(5到8)min(7到10);
  • [5,10]=min(d[5][2],d[7][2]);

    则 k=lg[r-l+1],ans=min(d[l][k],d[r-(1<<k)+1][k])

    求最大值,同理

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    int d1[500006][20];
    int d2[500006][20];
    int q[500006];
    int lg[500006];
    int n,m;
    void stb(){
    lg[0]=-1 , lg[1]=0;
    for(int i=2;i<=n;i++) lg[i]=lg[i>>1]+1;
    for(int j=1;j<=20;j++) {
        for(int i=1;i+(1<<j)-1<=n;i++) {
            cout<<i<<' '<<i+((1<<j))-1<<endl;
            cout<<i<<' '<<(i+(1<<(j-1)))-1<<"  **  "<<i+(1<<(j-1))<<' '<<i+(1<<(j-1))+(1<<(j-1))-1<<endl<<endl;
            d1[i][j]=min(d1[i][j-1],d1[i+(1<<(j-1))][j-1]);
            d2[i][j]=max(d2[i][j-1],d2[i+(1<<(j-1))][j-1]);
        }
    }
    }
    int mi(int l,int r){
    int k=lg[r-l+1];
    return min(d1[l][k],d1[r-(1<<k)+1][k]);
    }
    int ma(int l,int r){
    int k=lg[r-l+1];
    return max(d2[l][k],d2[r-(1<<k)+1][k]);
    }
posted on 2023-05-05 19:40  IR101  阅读(7)  评论(0编辑  收藏  举报  来源