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

Description

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

Input

第一行两个整数,M和D,其中M表示操作的个数(M <= 200,000),D如上文中所述,满足(0

Output

对于每一个查询操作,你应该按照顺序依次输出结果,每个结果占一行。

Sample Input

5 100
A 96
Q 1
A 97
Q 1
Q 2

Sample Output

96
93
96

HINT

【分析】

Orz。。。无所不能的树状数组,自己看代码看得懂吧。。。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <vector>
 6 #include <utility>
 7 #include <iomanip>
 8 #include <string>
 9 #include <cmath>
10 #include <map>
11
12 const int MAXN = 200000 + 10;
13 const int MAX = 32000 + 10;
14 using namespace std;
15 typedef long long ll;
16 ll m, MOD, l;
17 ll C[MAXN], num[MAXN];
18
19 void init(){
20      memset(C, 0, sizeof(C));
21      l = 0;//l代表的是整个序列的长度
22      scanf("%lld%lld", &m, &MOD);
23
24 }
25 ll lowbit(ll x) {return x & -x;}
26 ll Max(ll l, ll r){
27     ll cnt = num[r];
28     while (l <= r){
29           cnt = max(cnt, num[r]);
30           for (--r; r - l >= lowbit(r); r -= lowbit(r)) cnt = max(cnt, C[r]);
31           //cnt = max(cnt, C[r]);
32     }
33     return cnt;
34 }
35 void work(){
36      ll last = 0;//表示上一次查询的答案
37      for (int i = 1; i <= m; i++){
38          char str[2];
39          scanf("%s", str);
40          if (str[0] == ‘Q‘){
41             int a;
42             scanf("%lld", &a);
43             last = Max(l - a + 1, l);
44             printf("%lld\n", last);//[a,l]区间内的最大值
45          }else{
46             ll x;
47             scanf("%lld", &x);
48             num[++l] = (x + last) % MOD;
49             C[l] = max(Max(l - lowbit(l) + 1, l - 1), (x + last) % MOD);
50
51          }
52      }
53 }
54
55 int main(){
56     int T;
57     #ifdef LOCAL
58     freopen("data.txt",  "r",  stdin);
59     freopen("out.txt",  "w",  stdout);
60     #endif
61     init();
62     work();
63     return 0;
64 }

时间: 2024-08-05 12:21:38

【BZOJ1012】【树状数组求区间最值】最大数maxnumber的相关文章

树状数组求区间最值

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

POJ 2761 Feed the dogs(树状数组求区间第K大)

题目链接: 戳我 题目大意:Jiajia要为宠物狗,宠物狗按成一排站好(1 < i <= n),第 i 只狗的喜欢程度是 a[i], 之后他会先喂某个区间内第k个 即 n 个数, m个询问,接着是 n个数 接下来 m 行,每行是 l r k即 l 到 r 这个区间第 k 小的数,每个询问输出一个答案,即 a[i] 求区间第k大有很多算法, 详见此博客 [数据结构练习] 求区间第K大数的几种方法 我用的树状数组解法,来自 树状数组从前往后求和,用来解第k大(或小)的数 poj 2985 The

树状数组求区间最大值(树状数组)(复习)

如题. 当遇到单点更新时,树状数组往往比线段树更实用. 算法: 设原数序列为a[i],最大值为h[i](树状数组). 1.单点更新: 直接更新a[i],然后再更新h[i].若h[i]的值有可能改变的,则表示区间一定包含i结点.那么就两层lowbit更新所有可能的h. 单点更新时间复杂度O(logn*logn) 1 void update(int x) 2 { 3 while(x<=n) 4 { 5 h[x]=a[x]; 6 for(int i=1;i<lowbit(x);i<<=1

树状数组求区间最大值

------  一直用 线段树 求区间最大值,想换种思路,用树状数组试试,肯定是可以的. 首先要对 树状数组的每个 i 所管理的区间有一定的理解.详见上篇博客: 树状数组(BIT)

树状数组维护区间最值

在区间求和时,我们只需求出 [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)

POJ2985 The k-th Largest Group[树状数组求第k大值 并查集]

The k-th Largest Group Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8807   Accepted: 2875 Description Newman likes playing with cats. He possesses lots of cats in his home. Because the number of cats is really huge, Newman wants to g

树状数组求第K小值 (spoj227 Ordering the Soldiers &amp;&amp; hdu2852 KiKi&#39;s K-Number)

题目:http://www.spoj.com/problems/ORDERS/ and http://acm.hdu.edu.cn/showproblem.php?pid=2852 题意:spoj227:告诉每个位置前面有多少个数比当前位置小,求出原序列.hdu2852:设计一个容器,支持几种操作:增加/删除元素,求容器中比a大的数中第k小的数是多少. 分析:两个题思路都是求数组里面的第K小的数.开始一直在找O(N*logN)的方法,后来发现O(N*logN*logN)也是可以过的...两步:和

Day2:T4用树状数组求逆序对

T4: 用树状数组求逆序对 A[I]为前缀和 推导 (A[J]-A[I])/(J-I)>=M A[j]-A[I]>=M(J-I) A[J]-M*J>=A[I]-M*I B[J]>=B[I] 之后就是求逆序对的事情了 然后这里学一下用树状数组的方法 原理是:树状数组是用来求区间和的是吧 就是按权值的区间统计那么可以BIT维护...然后扫一遍 也就是计算有多少个逆序对 按权值的区间统计就是记录数的个数

poj2299(离散化+树状数组求逆序)

数据范围比较大,先用离散化将数据映射到可控的范围,然后应用树状数组求逆序求解. 总共有N个数,如何判断第i+1个数到最后一个数之间有多少个数小于第i个数呢?不妨假设有一个区间 [1,N],只需要判断区间[i+1,N]之间有多少个数小于第i个数.如果我们把总区间初始化为0,然后把第i个数之前出现过的数都在相应的区间把它的值定为1,那么问题就转换成了[i+1,N]值的总和.再仔细想一下,区间[1,i]的值+区间[i+1,N]的值=区间[1,N]的值(i已经标记为1),所以区间[i+1,N]值的总和等