洛谷1198最大数(线段树)

题目描述

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

输入输出格式

输入格式:

第一行两个整数,M和D,其中M表示操作的个数(M <= 200,000),D如上文中所述,满足(0<D<2,000,000,000)
接下来的M行,每行一个字符串,描述一个具体的操作。语法如上文所述。

输出格式:

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

输入输出样例

输入样例#1:
5 100
A 96
Q 1
A 97
Q 1
Q 2
输出样例#1:
96
93
96

说明

[JSOI2008]

洛谷ac

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
#define ll int
using namespace std;
const int maxn=800005;
const ll inf=(ll)2147483648;
ll _max[maxn],a[maxn],mod,ans=0,x;
int m,p=0,ql,qr;
inline ll get(){
    char c;bool f=0;while(!isdigit(c=getchar()))if(c=='-')f=1;
	ll v=c-48;while(isdigit(c=getchar()))v=v*10+c-48; 
	if(f)v=-v;return v;
}
inline void update(int node,int l,int r){
    if(l==r)a[p]=_max[node]=x;
    else{
		int mid=(l+r)>>1;
	    if(p<=mid)update((node<<1),l,mid);
	    else update((node<<1)+1,mid+1,r);
		_max[node]=max(_max[(node<<1)],_max[(node<<1)+1]);
	}
}
inline ll query(int node,int l,int r){
	ll mx=-inf;
    if(ql<=l && qr>=r)mx=_max[node];
    else{
		int mid=(l+r)>>1;
	    if(ql<=mid)mx=max(query((node<<1),l,mid),mx);
	    if(qr>mid)mx=max(query((node<<1)+1,mid+1,r),mx);
	}
	return mx;
}
int main(){
    m=(int)get();mod=get();
    for(int i=1;i<=m;++i){
	    char c;
	    scanf("%c",&c);
	    if(c=='A'){
		    ++p;
		    x=(int)get(); 
		    x=(x%mod+ans%mod)%mod;
		    update(1,1,m);
		}
		else{
			int l=(int)get();
			if(l<=0)continue;
			ql=p-l+1;qr=p;
		    ans=query(1,1,m);
		    printf("%d\n",ans);
		}
	}
	return 0;
}


bzojac

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
#define ll long long
using namespace std;
const int maxn=800005;
const ll inf=(ll)2147483648;
ll _max[maxn],a[maxn],mod,ans=0,x;
int m,p=0,ql,qr;
inline ll get(){
    char c;bool f=0;while(!isdigit(c=getchar()))if(c=='-')f=1;
	ll v=c-48;while(isdigit(c=getchar()))v=v*10+c-48; 
	if(f)v=-v;return v;
}
inline void update(int node,int l,int r){
    if(l==r)a[p]=_max[node]=x;
    else{
		int mid=(l+r)>>1;
	    if(p<=mid)update((node<<1),l,mid);
	    else update((node<<1)+1,mid+1,r);
		_max[node]=max(_max[(node<<1)],_max[(node<<1)+1]);
	}
}
inline ll query(int node,int l,int r){
	ll mx=-inf;
    if(ql<=l && qr>=r)mx=_max[node];
    else{
		int mid=(l+r)>>1;
	    if(ql<=mid)mx=max(query((node<<1),l,mid),mx);
	    if(qr>mid)mx=max(query((node<<1)+1,mid+1,r),mx);
	}
	return mx;
}
int main(){
    m=(int)get();mod=get();
    for(int i=1;i<=m;++i){
	    char c;
	    scanf("%c",&c);
	    if(c=='A'){
		    ++p;
		    x=(int)get(); 
		    x=(x%mod+ans%mod)%mod;
		    update(1,1,m);
		}
		else{
			int l=(int)get();
			if(l<=0)continue;
			ql=p-l+1;qr=p;
		    ans=query(1,1,m);
		    printf("%lld\n",ans);
		}
	}
	return 0;
}




思路:裸的线段树点修改;

注意:队列的位置和结点的区别。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值