zoukankan      html  css  js  c++  java
  • [模板][二分]倍增及其应用

    基础入门


    给定数组 和 数字T, 求最大位置K 满足 sum(1 - k) <= t;


    最简单的想法就是 前缀和 + 二分, 每次查询时间复杂度log(n), 对于数列最左端的数据没有必要

    这里的倍增可以理解为二分的改良优化版,

    设K点为0, P点为1

    1. 每次试从当前点K往后加P个数是否小于T

    以log速度快速使K逼近答案点

    2.随后再把P值快速缩向条件1, 返回1

    当P为零时K即为答案

    typedef long long ll;
    
    const int MAXN = 1e6 + 10;
    
    ll arr[MAXN] = {0};
    ll brr[MAXN] = {0};
    
    {
        ll n;
    
        cin >> n;
    
        for(int i = 1; i <= n; ++i)
        {
        	cin >> arr[i];
        	brr[i] = arr[i] + brr[i - 1];
        	cout << brr[i] << ' ';
        }
    
        ll t;
    
        while( cin >> t)
        {
    		ll p = 1, k = 0, sum = 0;
    		
    		while(p)
    		{
    			if(p + k <= n && sum + brr[p + k] - brr[k] <= t)
    			{
    				sum += (brr[p + k] - brr[k]);
    				k += p, p *= 2;
    			}
    			else
    				p /= 2;
    		} 
    		cout<< k <<'
    ';
    	}
    
        return 0;
    }
    
    /*
    6
    1 2 3 4 5 6
    20
     */

    ST 算法 RMQ

    ST算法是区间倍增保存信息的典型例子

    树高log2(n) + 1, 第i行的每个结点保存从原数组当前位之后 (1 << (i - 1)) 的最大值

    很容易发现最大值不断传递并符合通式 rmq[i][j] = max(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1) )]);

    查询时  把区间分成可以交叉的两部分 l 到 l + 2 ^(k)- 1, 到 r  - (1 << k) + 1 到 r 的两部分取最值即可


    输入, 树的第零层

    int n;
    
    cin >> n;
    
    for(int i = 0; i < n; ++i)
    {
    	cin >> rmq[0][i];
    }

    预处理 从第二层到第 log2(n) + 1 层

    void init_st(int n)
    {
    	int len = log2(n) + 1;
    
        for(int i = 1; i < len; ++i)
        {
        	for(int j = 0; j <= n - (1 << i) + 1; ++j)
        	{
        		rmq[i][j] = max(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1) )]);
        	}
        }
    }
    

    查询组成区间求最值

    ll query_st(int fst, int lst)
    {
    	int k = log2(lst - fst + 1);
    	return max(rmq[k][fst], rmq[k][lst - (1 << k) + 1]);
    }
  • 相关阅读:
    css动画特效
    http标码集合
    vue的搭建项目
    多功能
    react官方脚手架搭建项目
    深入挖掘分析Go代码
    GoLang AST简介
    GoLang中的逃逸分析简介
    使用Golang实现状态机
    GoLang中的Context
  • 原文地址:https://www.cnblogs.com/zeolim/p/12270384.html
Copyright © 2011-2022 走看看