zoukankan      html  css  js  c++  java
  • ST表

    ST表

    ST表用来实现O(logn)预处理,O(1)查询区间最值。

    不支持修改

    适用于O(logn)查询区间最值会被卡的情况。

    以查询最大值为例。

    预处理:记(f_{i,k})表示从i开始(2^k)个数的最大值,则

    (f_{i,k})=max((f_{i,k}),(f_{i+2^{k-1}}),k-1)。

    查询:设查询区间[l,r],令p为满足(2^Pleq r-l+1)的最大值,则答案为
    max((f_{l,p}),(f_{r-2^P+1}),p)。

    用两个长度为(2^p)的区间去覆盖查询区间,由于查询区间的长度属于[(2^p,2^{p+1})),故一定能够完整覆盖

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    
    using namespace std;
    
    const int maxn=1e6+10;
    int m,n,l,r,k;
    int a[maxn][21];
    
    inline int read()
    {
    	int x=0,f=1;char ch=getchar();
    	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
    	while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    	return x*f;
    }
    
    int query(int l,int r)
    {
    	int k=log2(r-l+1);
    	return max(a[l][k],a[r-(1<<k)+1][k]);
    }
    
    int main()
    {
    	n=read(),m=read();
    	for(int i=1;i<=n;i++)
    		a[i][0]=read();
    	for(int j=1;j<=21;j++)
    		for(int i=1;i+(1<<j)-1<=n;i++)
    			a[i][j]=max(a[i][j-1],a[i+(1<<(j-1))][j-1]);
    	for(int i=1;i<=m;i++)
    	{
    		l=read(),r=read();
    		printf("%d
    ",query(l,r));
    	}
    	return 0;
    }
    

    题目推荐

    洛谷P2048 超级钢琴 (NOI2010)

  • 相关阅读:
    ajax_基础1
    省市数据库脚本TblArea.
    c#中怎么使用dos命
    Lambda表达式
    面试收录
    .Net牛逼程序猿要懂得
    Web.config 配置文件
    sql 查询所有数据库、表名、表字段总结
    Json在net与页面之间的传递
    『转』SAP统驭科目解释
  • 原文地址:https://www.cnblogs.com/liumengliang/p/13337555.html
Copyright © 2011-2022 走看看