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
A 96
Q 1
A 97
Q 1
Q 2
Sample Output
96
93
96
93
96
HINT
刚看题目的时候吓了一跳,这么裸的线段树真的是省选题目么
然后就觉得不对劲,想了想,不会是splay吧?
可惜我等蒟蒻实在是懒得打splay(其实我早就发现这不是splay了.。。机智如我)
于是果断打了线段树,然后。。A了
代码如下:
#include<cstdio>#include<iostream>#include<cstdlib>using
namespace std;typedef
long long
LL;const
int maxn=200010,Max=0x7fffffff;int
m,len,d;char ch;LL t[maxn*4],tmp,n;LL max(LL a,LL b){ if(a>b)return
a; return
b;}void
update(int o,int
l,int
r,int loc,LL v){ if(l==r){t[o]=v;return;} int
ll=o<<1,rr=ll|1,mid=(l+r)>>1; if(loc<=mid)update(ll,l,mid,loc,v); else
update(rr,mid+1,r,loc,v); t[o]=max(t[ll],t[rr]);return;}LL ask(int
o,int
l,int r,int
x,int
y){ if(l>=x&&r<=y){return
t[o];} int
ll=o<<1,rr=ll|1,mid=(l+r)>>1; if(y<=mid)return
ask(ll,l,mid,x,y); else
if(x>mid)return
ask(rr,mid+1,r,x,y); else
return max(ask(ll,l,mid,x,y),ask(rr,mid+1,r,x,y));}int
main(){ scanf("%d%d",&m,&d); for(int
i=1;i<=m;++i)t[i]=-Max; for(int
i=1;i<=m;++i){ ch=getchar(); while(ch<'!')ch=getchar(); scanf("%lld",&n); if(ch=='A'){ n=(n+tmp)%d; update(1,1,m,len+1,n);len++; } else{ tmp=ask(1,1,m,len-n+1,len); printf("%lld\n",tmp); } }return
0;}
但是呢,这道题目由于题目本身具有特殊性,主要是插入和询问都是只对末尾进行操作
所以我们可以用一个单调队列维护一下,这个的思想比较巧妙,唯一不好的是如果给的是一个上升序列就GG了
代码如下:
#include<cstdio>#include<iostream>#include<algorithm>#include<cstdlib>using
namespace std;const
int maxn=200010;typedef
long long
LL;int
q[maxn],max_[maxn],m,d,len;char
ch;LL n,tmp;int
main(){ scanf("%d%d",&m,&d); for(int
i=1;i<=m;++i){ ch=getchar(); while(ch<'!')ch=getchar(); scanf("%lld",&n); if(ch=='A'){ n=(n+tmp)%d;len++;q[len]=n; for(int
i=len;i;--i){ if(max_[i]<q[len])max_[i]=q[len]; else
break; } } else{ tmp=max_[len-n+1]; printf("%lld\n",tmp); } } return
0;}
本文介绍了如何通过线段树和单调队列解决特定数列操作问题,包括查询和插入操作。重点在于实现高效的数据结构以满足题目要求,通过实例演示了解题过程。
566

被折叠的 条评论
为什么被折叠?



