zoukankan      html  css  js  c++  java
  • 倍增算法

    倍增算法

    RMQ(区间最值查询)
    主要思想就是区间dp出每个点起2的k次方的长度内的极值。运用大区间的极值由小区间得到,同时大区间的答案可以由小区间随意组合得到。比如我们已经预处理1为起点长度为4的答案,和2为起点向后4的答案,我们查询区间1到5的极值就可以比较1-4区间和2-5区间的答案来得到1-5的答案
    二维DP数组:ST表
    ST表数组:f[i][j],表示区间【i,i+2j-1】的最大值。这个区间的大小是2j个数。
    ST表的初始化:f[i][0]=a[i]。(显然这是区间大小为1的时候)
    ST表的递推过程:

    1. 由区间大小为1的项转移得到区间大小为21的项
    2. 由区间为21的项转移得到区间为22的项
    3. 由区间为22的项转移得到区间为23的项
    /*
    在递推时,把子区间的长度成倍增长
    另F[i,j]表示数列A中下标在子区间[i,i+2^j-1]里的数的最大值
    F[i,j]=max(F[i,j-1],F[i+2^j-1,j-1]) 
    */
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    //log函数 
    using namespace std;
    int f[10000][100];
    int a[10000];
    int N;
    //预处理 
    void ST_prework()
    {
    	for(int i=1;i<=N;i++)
    		f[i][0]=a[i];
    	int t=log(N)/log(2)+1; //log2N
    	for(int j=1;j<t;j++)
    	{
    		for(int i=1;i<=N-(i<<j)+1;i++)
    		{
    			f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
    		}
    	}
    }
    int ST_query(int l,int r)
    {
    	int k=log(r-l+1)/log(2);
    	return max(f[l][k],f[r-(1<<k)+1][k]);
    }
    int main()
    {
    	cin>>N;
    	int n,m;
    	cin>>n>>m;
    	for(int i=1;i<=N;i++)
    		cin>>a[i];
    	cout<<ST_query(n,m)<<endl;
    	return 0;
    }
    
  • 相关阅读:
    nginx工作原理
    nginx源码安装与使用
    Nginx内置变量以及日志格式变量
    Nginx配置参数中文详细说明
    shell-处理用户输入
    Shell编程进阶篇(完结)
    高斯消元
    S-T平面图
    Kruskal重构树
    NOIP2016天天爱跑步 题解报告【lca+树上统计(桶)】
  • 原文地址:https://www.cnblogs.com/serendipity-my/p/12825751.html
Copyright © 2011-2022 走看看