您的位置:首页 > Web前端 > JavaScript

[JSOI2008]最大数maxnumber

2015-07-27 17:35 676 查看

1012: [JSOI2008]最大数maxnumber

Time Limit: 3 Sec  Memory Limit: 162 MB
Submit: 5667  Solved: 2461
[Submit][Status][Discuss]

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

 

Source

                           [Submit][Status][Discuss]

    1.单调队列,比较好理解,就是如果要新加入的数比前面若干个数大,就把这若干个数覆盖掉,通俗点说,又靠后值又大的数比较diao,因为撑死20w个数,所以开两个20w的数组就够了。   我们平时写单调队列时,貌似比较多的是用两个指针head,tail来维护队列Q[]数组,但这题貌似行不通,因为每次询问的L不固定,不能舍弃数列的任意一部分,所以用了“覆盖”的方法。

  注意:在输入字符A或Q时,如果像我下面那样定义ch[5],用 cin>>ch 是错的,要用scanf("%s",ch); 否则会RE,我也不知道为啥

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int Q[200005];
int a[200005];
char ch[5];
int L,N,T,D,M,tot;
inline void workA();
inline void workQ();
int main(){
cin>>M>>D;
for(int i=1;i<=M;i++){
scanf("%s",ch);
//cin>>ch;//RE的
if(ch[0]=='A')
workA();
else
workQ();
}
return 0;
}
inline void workA(){
scanf("%d",&N);
a[++tot]=(T+N)%D;
for(int i=tot;i;i--){
if(Q[i]<a[tot])
Q[i]=a[tot];
else break;
}
}
inline void workQ(){
scanf("%d",&L);
printf("%d\n",T=Q[tot-L+1]);
}

  

  2.用线段树,相比之下太长了,还容易错,就不分析了,网上随便整的一个代码

  

#include<iostream>
#include<cstdio>
#define inf 0x7fffffff
using namespace std;
int m,mod,last,cnt;
struct data{int l,r,mx;}t[800005];
void build(int k,int l,int r)
{
t[k].l=l;t[k].r=r;t[k].mx=-inf;
if(l==r)return;
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
}
int ask(int k,int x,int y)
{
int l=t[k].l,r=t[k].r;
if(l==x&&r==y)return t[k].mx;
int mid=(l+r)>>1;
if(y<=mid)return ask(k<<1,x,y);
else if(x>mid)return ask(k<<1|1,x,y);
else return max(ask(k<<1,x,mid),ask(k<<1|1,mid+1,y));
}
void insert(int k,int x,int y)
{
int l=t[k].l,r=t[k].r;
if(l==r){t[k].mx=y;return;}
int mid=(l+r)>>1;
if(x<=mid)insert(k<<1,x,y);
else insert(k<<1|1,x,y);
t[k].mx=max(t[k<<1].mx,t[k<<1|1].mx);
}
int main()
{
scanf("%d%d",&m,&mod);
build(1,1,m);
for(int i=1;i<=m;i++)
{
char ch[5];scanf("%s",ch);
int x;
if(ch[0]=='A')
{
cnt++;
scanf("%d",&x);x=(x+last)%mod;
insert(1,cnt,x);
}
else
{
scanf("%d",&x);
last=ask(1,cnt-x+1,cnt);
printf("%d\n",last);
}
}
return 0;
}

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: