• Luogu P3865 【模板】ST表


    (Luogu) (P3865) 【模板】(ST)

    ST 表是用于解决 可重复贡献问题 的数据结构。

    可重复贡献问题 是指对于运算(opt),满足(x opt x=x),则对应的区间询问就是一个可重复贡献问题。例如,最大值有(max(x,x)=x)(gcd)(gcd(x,x)=x),所以(RMQ) 和区间(GCD)就是一个可重复贡献问题。像区间和就不具有这个性质,如果求区间和的时候采用的预处理区间重叠了,则会导致重叠部分被计算两次,这是我们所不愿意看到的。另外,(opt)还必须满足结合律才能使用(ST)表求解。

    (RMQ)是英文 (Range Maximum/Minimum Query)的缩写,表示区间最大(最小)值。解决(RMQ)问题有很多种方法,可以参考 RMQ 专题

    ——引自(OI) (Wiki)

    (ST)表适用于没有修改的区间最大值问题,当然如果数据强度不高,树状数组和线段树也是一个很好地选择。

    树状数组做法

    线段树做法(cal {LZ})有话说:大概是自己的线段树常数太大,并不能快乐的(AC)

    (ST)表基于倍增的思想,可以做到(O(nlogn))预处理,(O(1))查询。

    记录(ST[i][j])为从(j)开始往后数(2^i)个这些数的最大值

    显然(ST[i][j])可以递推求出:(ST[i][j]=max(ST[i-1][j],ST[i-1][j+2^{i-1}]);)

    初始:(ST[0][i]=a[i];)

    求一个区间([l,r])的最大值:

    (frak{a}).求出区间长度:(k=l-r+1)

    (frak{b}).记录(p=log_2k)

    (frak{c}).求这个区间的最大值(max(ST[p][l],ST[p][r-2^p+1]))

    (log_2x)的处理:

    Log[0]=-1;
    for(int i=1;i<=n;++i) 
        Log[i]=Log[i>>1]+1;
    

    #include<bits/stdc++.h>
    #define N 100005
    #define K 21
    
    using namespace std;
    
    int m,n,p,k,ST[K+1][N],a[N],Log[N];
    
    inline int read() {
    	int ans=0;
    	char last=' ',ch=getchar();
    	while(ch>'9'||ch<'0') last=ch,ch=getchar(); 
    	while(ch>='0'&&ch<='9') ans=(ans<<1)+(ans<<3)+ch-'0',ch=getchar();
    	if(last=='-') ans=-ans;
    	return ans;
    }
    
    int Find(int l,int r)
    {
        int x=Log[r-l+1];
        return max(ST[x][l],ST[x][r-(1<<x)+1]); 
    }
    
    int main() {
        n=read();m=read();
        Log[0]=-1;
        for (int i=1;i<=n;++i) {
    		ST[0][i]=read();
    		Log[i]=Log[i>>1]+1;
    	}
        for (int i=1;i<=K;++i)
            for (int j=1;j+(1<<i)-1<=n;++j)
                    ST[i][j]=max(ST[i-1][j],ST[i-1][j+(1<<(i-1))]);                                                       
        for(int i=1,l,r;i<=m;++i) {
            l=read();r=read();
            printf("%d
    ",Find(l,r));
        }
        return 0;   
    }
    
  • 相关阅读:
    通用分页后台显示
    自定义的JSP标签
    Java反射机制
    Java虚拟机栈---本地方法栈
    XML建模实列
    XML解析与xml和Map集合的互转
    [离散数学]第二次作业
    [线性代数]2016.10.13作业
    [数字逻辑]第二次作业
    [线性代数]2016.9.26作业
  • 原文地址:https://www.cnblogs.com/zhuier-xquan/p/12912529.html
Copyright © 2020-2023  润新知