最大数
最 大 数 最大数 最大数
题目
现在请求你维护一个数列,要求提供以下两种操作:
- 查询操作。
语法: Q Q Q L L L
功能:查询当前数列中末尾 L L L个数中的最大的数,并输出这个数的值。
限制: L L L不超过当前数列的长度。 ( L > 0 ) (L>0) (L>0) - 插入操作。
语法: A A A n n n
功能:将 n n n加上 t t t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则 t = 0 t=0 t=0),并将所得结果对一个固定的常数 D D D取模,将所得答案插入到数列的末尾。
限制: n n n是整数(可能为负数)并且在长整范围内。
注意:初始时数列是空的,没有一个数。
输入
第一行两个整数,
M
M
M和
D
D
D,其中
M
M
M表示操作的个数,
D
D
D如上文中所述。
接下来的
M
M
M行,每行一个字符串,描述一个具体的操作。语法如上文所述。
输出
对于每一个查询操作,你应该按照顺序依次输出结果,每个结果占一行。
样例输入
5 100
A 96
Q 1
A 97
Q 1
Q 2
样例输出
96
93
96
数据范围
M
≤
200
,
000
M≤200,000
M≤200,000
0
<
D
<
2
,
000
,
000
,
000
0<D<2,000,000,000
0<D<2,000,000,000
思路
首先,这道题是线段树题。
每一次的插入就可以当做在原来的基础上继续建树(但每次只建一个点),然后查询就是区间最大值。
注意:要用
l
o
n
g
long
long
l
o
n
g
long
long!!!
(本人就因为一直用
i
n
t
int
int而卡了很久很久)
代码
#include<cstdio>
#include<iostream>
using namespace std;
long long tree[800001],m,d,t,x,n;
char c;
long long answer(long long now,long long l,long long r,long long left,long long right)//查询操作
{
if (l>=left&&r<=right) return tree[now];
long long mid=(l+r)/2,temp=-2147483647;
if (left<=mid) temp=answer(now*2,l,mid,left,right);
if (right>mid) temp=max(temp,answer(now*2+1,mid+1,r,left,right));
return temp;
}
void add(long long l,long long r,long long sum)//插入操作
{
if (l==r)
{
tree[sum]=(x+t)%d;
return ;
}
long long mid=(l+r)/2;
if (n<=mid) add(l,mid,sum*2);
else add(mid+1,r,sum*2+1);
tree[sum]=max(tree[sum*2],tree[sum*2+1])%d;
return;
}
int main()
{
cin>>m>>d;//读入
for (long long i=1;i<=m;i++)
{
cin>>c;//读入
cin>>x;//读入
if (c=='A')//插入操作
{
n++;
add(1,m,1);
}
else cout<<(t=answer(1,1,m,n-x+1,n))<<"\n";//查询操作
}
return 0;
}
相关文章
- 信奥赛一本通2038:【例5.5】最大数位置
- 【LeetCode】最大数 [M](贪心)
- Java_oracle超出打开游标的最大数的原因和解决方案
- 【BZOJ】1012: [JSOI2008]最大数maxnumber(树状数组+rmq)
- LeetCode_排序_中等_179.最大数
- leetcode179. 最大数
- 第三章习题3--第七题==判断阶乘和的最大数
- 1275. 最大数
- P1198最大数——线段树点修改&&模板题
- AcWing 1275. 最大数
- C++ 数组 求最大数并和最后一个数交换和最小数并和第一个数交换
- 字节面试算法题:用集合中的数凑小于target的最大数(Java实现,各类用例均通过)
- leetcode 179 最大数
- 【至少是其他数字两倍的最大数(747-java)】