[JSOI2008]最大数 线段树解法
2024-10-21 03:58:43
题目描述
现在请求你维护一个数列,要求提供以下两种操作:
1、 查询操作。
语法:Q L
功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。
限制:L不超过当前数列的长度。
2、 插入操作。
语法:A n
功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾。
限制:n是整数(可能为负数)并且在长整范围内。
注意:初始时数列是空的,没有一个数。
--by luogu
https://daniu.luogu.org/problem/show?pid=1198
先把序列的空位建好线段树,初始序列是空的,就先建为极小值(注意她是负的),对每个A操作,就是在相应位置单点修改,对每个Q操作,就是查询相应的位置的区间最值
位置是什么呢?
发现只要记下当前序列的结尾就迎刃而解啦;
代码如下:
#include<cstdio>
using namespace std;
long long D,n,t;
int tree[];
int m,len;
void build(int ,int ,int );
void change(int ,int, int ,int );
int MAX(int ,int ,int ,int ,int );
int main()
{
int i,j,k,l;
char c;
scanf("%d%d",&m,&D);
build(,m,);
for(i=;i<=m;i++){
c=getchar();
while(c!='A'&&c!='Q')
c=getchar();
if(c=='A'){
scanf("%lld",&n);
n=(n+t)%D;
change(,m,,len+);
len++;
}
if(c=='Q'){
scanf("%d",&l);
t=MAX(,m,,len-l+,len);
printf("%lld\n",t);
}
}
return ;
}
void build(int l,int r,int nu){
if(l==r){
tree[nu]=-;
return;
}
int mid=(l+r)>>;
build(l,mid,nu<<);build(mid+,r,nu<<|);
tree[nu]=-;
}
void change(int l,int r,int nu,int x){
if(l==r){
tree[nu]=n;
return ;
}
int mid=(l+r)>>;
if(x<=mid)
change(l,mid,nu<<,x);
else
change(mid+,r,nu<<|,x);
if(tree[nu<<]>tree[nu<<|])
tree[nu]=tree[nu<<];
else
tree[nu]=tree[nu<<|];
}
int MAX(int l,int r,int nu,int L,int R){
if(L<=l&&r<=R)
return tree[nu];
int mid=(l+r)>>;
int Lmax=-,Rmax=-;
if(L<=mid)
Lmax=MAX(l,mid,nu<<,L,R);
if(R>=mid+)
Rmax=MAX(mid+,r,nu<<|,L,R);
if(Lmax>Rmax)
return Lmax;
return Rmax;
}
话说代码真难看呵;
最新文章
- CC_STACKPROTECTOR防内核堆栈溢出补丁分析【转】
- 常用到的git,mvn,postgres,vim命令总结
- [Java]Hessian客户端和服务端代码例子
- 树状数组 + 位运算 LA 4013 A Sequence of Numbers
- Web分布式部署,跨应用程序Forms身份验证的集成方案
- 2015北京网络赛B题 Mission Impossible 6
- jQuery 小知识点(插件)
- 向PE文件中添加一个Section
- 第3.3.4节 创建高级图形之RenderScript(二)
- 异步编程和线程的使用(.NET 4.5 )
- 基于STM32的USB枚举过程学习笔记
- Codeforces #Round 406(Div.2)
- 微信小程序开发基础
- web爬虫,requests请求
- 【Tensorflow】tensorboard
- POJ 3662	Telephone Lines (二分 + 最短路)
- 快排 - 快速排序算法 (Chinar出品 简单易懂)
- 5_Python OOP
- python 语法最佳实践
- 中点Brehensam画圆算法