算法笔记:ST表与倍增算法

一.ST表的含义

ST表其实就是一种特殊的区间dp,但与普通区间dp不同的是,ST表只维护了部分区间信息。

ST表的‘S’意思就是sparse,稀疏的,ST表只维护区间长度为2的倍数的区间信息。

区间dp:dp[l][r],代表区间(l,r)上维护的信息

ST表:ST[l][p],代表区间(l,l+2^p-1)上维护的信息,l代表区间左端点,p代表区间长度。

二.ST的用法
1.经典用法

线段上有n个点,每个点i能往前跳jump[i]个距离,当i<j时,必有jump[i]<=jump[j],计算出任意两点间的最少跳跃步数。

注意红字,这是能使用ST表的必要条件,意思是越靠前的点,能跳到的位置一定越靠前(也可以理解为,没有一个区间是完全包含另一个去区间的(最差情况是区间的左端点或右端点重合))。

也就是说,当满足一定的单调性,才能使用ST表。

转移方程式:ST[i][j] = ST[ST[i][j-1]][j-1]

利用转移方程式构建完ST表后,当求区间(l,r),设步长为step,从l开始,先另step选取最大步长,如果当前跳跃步数到达的位置不超过r(ST[cur][step]<r),就记录一下。step每次减少一半,用逐步逼近的方式计算最近距离。

结果要加一(每次到达的位置<r,因此肯定还没到达r;因为我们是按照2^n严格逼近的,不可能出现差2步或更多步的情况)。

#define N 100000
int length;//区间长度
int power;//log2(区间长度)
int ST[N][31];
int jump[N];

//建立ST表
void build(){
    power = log2(length);
    for(int i = 0;i<N;i++){
        ST[i][0] = i+jump[i]-1;
    }
    for(int j = 0;j<= length;j++){
        for(int i = 0;i<n;i++){
            ST[i][j] = ST[ST[i][j-1]][j-1];
        }
    }
}

int query(int l,int r){
    int ans = 0,next,cur = l;
    for(int i = power;i>=0;i--){
        next = ST[cur][i];
        if(next!=-1&&next<r){
            ans+=1<<i;
            cur = next;
        }
    }
    return ans+1;
}
   
int main(){
    memset(ST,-1,sizeof(ST));
    build();
    while(true){
         int l,r;cin>>l>>r;
         cout<<query(l,r)<<endl;
    }
}
2.区间可重复贡献度问题

区间可重复贡献度问题,即区间a被划分为区间b和区间c,且b和c有交集,但是仍能从b和c维护的信息中得到a的信息。

典型的如区间最值,区间gcd(最大公约数),区间按位与、按位或。

以区间最大值为例

int nums[N];//目标数组
int ST[N][31];

void build(){//构建ST表
    for(int i = 0;i<n;i++){
        ST[i][0] = nums[i];
    }
    int power = log2(N);
    for(int j = 1;j<=power;j++){
        for(int i = 0;i<n;i++){
            ST[i][j] = max(ST[i][j-1],ST[i+(1<<(j-1)][j-1]);
        }
    }
}

int query(int l,int r){//查询区间最大值
    int power = log2(r-l+1);
    return max(ST[l][power],ST[r-(1<<power)+1][r]);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值