BZOJ 1012: [JSOI2008]最大数maxnumber

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

 http://www.lydsy.com/JudgeOnline/problem.php?id=1012

/*
* 分析:
* 单调队列加暴力。
* 这个程序优化的地方:可以只存标号,每次Q操作的时候直接二分。
* */

#include <cstdio>

#include <cstring>

#include <iostream>



using namespace std;



const int X = 200005;



struct node{

	int id,val;

}q[X];



int main(){

	int n,m;

	while(cin>>n>>m){

		int pre = 0;

		int x;

		char op[2];

		int head = 0,tail = 0;

		int len = 0;

		for(int i=1;i<=n;i++){

			scanf("%s%d",op,&x);

			if(op[0]=='A'){

				x = (x+pre)%m;

				while(tail&&q[tail-1].val<=x)

					tail --;

				q[tail].val = x;

				q[tail++].id = ++len;

			}

			else{

				for(int j=tail-1;j>=0;j--){

					if(q[j].id+x<=len)

						break;

					else

						pre = q[j].val;

				}

				printf("%d\n",pre);

			}

		}

	}

	return 0;

}

  

第二种方法:

/*
* 分析:
* 建立线段树
* 对于A操作,只需要update一下
* 对于Q操作,只需要query一下就好了。。
*
* */

#include <cstdio>

#include <cstring>

#include <iostream>



using namespace std;



const int X = 200002;



#define debug puts("here");



struct seg_tree{

	int l,r;

	int val;

	int mid(){

		return (l+r)>>1;

	}

}tree[X<<2];



void build(int l,int r,int rt){

	tree[rt].l = l;

	tree[rt].r = r;

	if(l==r)

		return;

	int mid = tree[rt].mid();

	build(l,mid,rt<<1);

	build(mid+1,r,rt<<1|1);

}



void update(int pos,int val,int rt){

	if(tree[rt].l==tree[rt].r){

		tree[rt].val = val;

		return;

	}

	int mid = tree[rt].mid();

	if(mid>=pos)

		update(pos,val,rt<<1);

	else

		update(pos,val,rt<<1|1);

	tree[rt].val = max(tree[rt<<1].val,tree[rt<<1|1].val);

}



int query(int l,int r,int rt){

	if(l<=tree[rt].l&&r>=tree[rt].r)

		return tree[rt].val;

	int mid = tree[rt].mid();

	int ans = 0;

	if(l<=mid)

		ans = max(ans,query(l,r,rt<<1));

	if(r>mid)

		ans = max(ans,query(l,r,rt<<1|1));

	return ans;

}



int main(){

	int n,m;

	while(cin>>n>>m){

		char op[2];

		int x;

		int pre = 0;

		int len = 0;

		build(1,n,1);

		while(n--){

			scanf("%s%d",op,&x);

			if(op[0]=='A')

				update(++len,(pre+x)%m,1);

			else{

				pre = query(len-x+1,len,1);

				printf("%d\n",pre);

			}

		}

	}

	return 0;

}

  

 

你可能感兴趣的:(number)