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

bzoj1012: [JSOI2008]最大数maxnumber[单调队列+二分]

2014-10-14 21:43 381 查看
这道题,算是单调队列的一个妙用了

其实我刚开始想的是平衡树,我感觉其实也可以做,但是后来画了几个例子,觉得好像不用那么麻烦。

这道题其实A的方法好多啊,搜了一下树状数组、平衡树、线段树什么的都有,还真是人有多大胆地有多大产。

但是既然单调队列就可以A,那就省点代码量咯。

想到单调队列由以下两点

1.如果一个节点在队列中既没有时间优势(早点入队)也没有值优势(值更大),那么显然无论在怎样的情况下都不会被选为最大值。

   既然它只在末尾选,那么自然可以满足以上的条件。

2.如果想要对这个数组进行二分查找满足条件的最大值,要求数组的值单调。

然而单调队列正好将以上两者完美的结合在一起。

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Code:

#include<iostream>
#include<cstdio>
using namespace std;

const int M=200010;

struct que{
int pos,v;
que(){}
que(int _v,int _pos){
v=_v; pos=_pos;
}
}q[M];
int m,d;

int main(){
int l,r,num,lastans=0;
int ll,rr,mid,ans,v;
char opt; r=0;
int cnt=0;
scanf("%d%d",&m,&d);
for(int i=1;i<=m;i++){
scanf("\n%c\n",&opt);
scanf("%d",&num);
if(opt=='A'){
v=(num+lastans)%d;
while(r&&q[r].v<v) r--;
q[++r]=que(v,++cnt);
}else{
ll=1; rr=r; ans;
mid=(ll+rr)>>1;
while(ll<=rr){
mid=(ll+rr)>>1;
if(cnt-q[mid].pos+1>num) ll=mid+1;
else{
ans=mid; rr=mid-1;
}
}printf("%d\n",q[ans].v);
lastans=q[ans].v;
}
}return 0;

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