树状数组维护区间最值

在区间求和时,我们只需求出 [1, r],[1,l?1],利用前缀和的可减性,得到区间 [l,r] 的和。

但区间最值不满足这个性质。

我们可以把区间 [l,r] 拆分成若干个子区间,再合并得到答案。

画图可知,max_i需要的 max 只有 max_{i-2^0}, max_{i-2^1}, max_{i-2^2} ... max_{i-lowbit(i)+1}。

修改

void change(int r) {
    c[r] = a[r];
    for(int i = 1; i < lowbit(r); i <<= 1)
        c[r] = max(c[r], c[r-i]);
}

查询

我们找 [l, r] 的最值就是子区间最值的 max,即递减 r,在这里可以有个优化,即当找到一个 max_i??,有 i?lowbit(i)≥l 时,更

新后,i = i - lowbit(i),然后继续递减。当 l>r 就跳出循环。

int getmax(int l, int r) {
    int ret = a[r];
    while(l <= r) {
        ret = max(ret, a[r]);
        for(--r; r - l >= lowbit(r); r -= lowbit(r))
            ret = max(ret, c[r]);
    }
    return ret;
}

需要指出的是,它只支持末端插入,不支持单点修改操作。

#include<iostream>
#include<stdio.h>
#include<memory.h>
using namespace std;
int A[200005];
int C[200005];
int lowbit(int x)
{
    return x&(-x);
}

void update(int x)
{
    C[x]=A[x];
    for(int i=1; i<lowbit(x); i<<=1)
        C[x]=max(C[x],C[x-i]);
}

int query(int l,int r)
{
    int ans=A[r];
    while(l<=r)
    {
        ans=max(ans,A[r]);
        for(--r; r-l>=lowbit(r); r-=lowbit(r))
            ans=max(ans,C[r]);
    }
    return ans;
}

int main()
{
    int m,d;
    scanf("%d%d",&m,&d);
    int cnt = 0,t=0;
    for(int i = 0; i<m; i++)
    {
        char op;
        int n;
        scanf(" %c%d",&op,&n);
        if(op==‘A‘)
        {
            int temp = (n+t)%d;
            A[++cnt]=temp;
            update(cnt);
        }
        else
        {
            printf("%d\n",t = query(cnt-n+1,cnt));
        }
    }
    return 0;
}
时间: 2024-10-11 16:36:18

树状数组维护区间最值的相关文章

树状数组求区间最值

树状数组求区间最值 树状数组(Binary Index Tree)利用二进制的一些性质巧妙的划分区间,是一种编程,时间和空间上都十分理想的求区间和的算法,同样我们可以利用树状数组优美的区间划分方法来求一个序列的最值 约定以 num[]  表示原数组, 以 idx[] 表示索引数组, Lowbit(x)=x&(-x) 树状数组求和时通过构造数组 idx[] 使 idx[k]=sum(num[tk]), tk [k-Lowbit(k)+1,k], 使用同样的方法构造最值索引数组: 以最大值为例, 先

2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ&#39;s Salesman 【离散化+树状数组维护区间最大值】

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 919    Accepted Submission(s): 290 Problem Description YJJ is a salesman who h

Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2) C. Fountains 【树状数组维护区间最大值】

题目传送门:http://codeforces.com/contest/799/problem/C C. Fountains time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Arkady plays Gardenscapes a lot. Arkady wants to build two new fountains. The

【BZOJ1012】【树状数组求区间最值】最大数maxnumber

Description 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度. 2. 插入操作.语法:A n 功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾.限制:n是非负整数并且在长整范围内.注意:初始时数列是空的,没有一个数. Input 第一行两个整数,M和D,其中M表示操作

【Hihocoder 1167】 高等理论计算机科学 (树链的交,线段树或树状数组维护区间和)

[题意] 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 少女幽香这几天正在学习高等理论计算机科学,然而她什么也没有学会,非常痛苦.所以她出去晃了一晃,做起了一些没什么意义的事情来放松自己.门前有一颗n个节点树,幽香发现这个树上有n个小精灵.然而这些小精灵都比较害羞,只会在一条特定的路径上活动.第i个小精灵会在ai到bi的路径上活动.两个小精灵是朋友,当且仅当它们的路径是有公共点的.于是幽香想要知道,有多少对小精灵a和b,a和b是朋友呢?其中a不等于b,a,b和b,

hdu 5654 xiaoxin and his watermelon candy 树状数组维护区间唯一元组

题目链接 题意:序列长度为n(1<= n <= 200,000)的序列,有Q(<=200,000)次区间查询,问区间[l,r]中有多少个不同的连续递增的三元组. 思路:连续三元组->递推O(n)将第一次出现该三元组的下标记录到树状数组中,并且用一个Next[]来表示递推关系,即同一个三元组下一次出现的位置是Next[x];这很关键,在之后按照左边界处理时(有点像莫队算法),一直递推在l+1左侧重复出现的三元组,为了把该三元组推到出现在[l,r]或者[r+1,..]中,这样不重不漏.

Codeforces Round #425 (Div. 2) D 树链剖分 + 树状数组维护区间

一看就知道 可以LCA判断做 也可以树链剖分拿头暴力 然而快速读入和线段树维护区间会T70 于是只能LCA? 线段树的常数不小 于是需要另外一种办法来进行区间加减和查询区间和 就是使用树状数组 这个题的代码 #include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<vector> #include<cstring> using na

codeforces round 512 F. Putting Boxes Together 树状数组维护区间加权平均数

F. Putting Boxes Together time limit per test 2.5 seconds memory limit per test 256 megabytes input standard input output standard output There is an infinite line consisting of cells. There are nn boxes in some cells of this line. The ii-th box stan

Codeforces1076E. Vasya and a Tree(dfs+离线+树状数组维护)

题目链接:传送门 题目: E. Vasya and a Tree time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Vasya has a tree consisting of n vertices with root in vertex 1. At first all vertices has 0 written on it.