您的位置:首页 > 其它

【单调栈】Bzoj 1012: 最大数maxnumber

2015-10-11 22:33 330 查看

1012: [JSOI2008]最大数maxnumber

Time Limit: 3 Sec Memory Limit: 162 MB
Submit: 6255 Solved: 2676
[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

  不小心水了一个单调栈过了。。(维护单调性二分)
  CLJ高级做法:http://wjmzbmr.com/archives/jsoi2008_maximum_number_maxnumber_of/  
  

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>

#define maxn 200001

typedef long long ll;

using namespace std;

struct node{
ll c;
int pos;
}sta[maxn];

ll top=0;

inline ll in()
{
ll x=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x;
}

void add(ll num,int pos)
{
while(sta[top].c<=num&&top!=0)top--;
top++;
sta[top].c=num,sta[top].pos=pos;
}

ll ask(int r,int pos)
{
int l=1,an;
while(l<=r)
{
int mid=(l+r)>>1;
if(sta[mid].pos>=pos)r=mid-1,an=mid;
else l=mid+1;
}
return sta[an].c;
}

int main()
{
int n,nownum=0;
ll d,num,lastans=0;
char sb;
n=in(),d=in();
for(int i=1;i<=n;i++)
{
sb=0;
while(sb!='A'&&sb!='Q')sb=getchar();
num=in();
if(sb=='Q')printf("%lld\n",lastans=ask(top,nownum-num+1));
else add((num%d+lastans%d)%d,++nownum);
}
return 0;
}


View Code
  ps:最近脑残各种小地方打错。。

  是时候考试开始写对拍了。。

  ps:初赛76简直了。。想想如果不是在HN而是ZJ而搞OI那早就以一种奇怪的方式结束OI生涯了。。而且错的貌似都是OI知识?(指针,容斥,catanlan什么的)。。感觉自己学的还是不是太扎实
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: