码迷,mamicode.com
首页 > Web开发 > 详细

JSOI2008 最大数

时间:2017-10-30 14:13:32      阅读:316      评论:0      收藏:0      [点我收藏+]

标签:stream   oid   个数   负数   ora   font   nbsp   查询   first   

题目: 

  现在请求你维护一个数列,要求提供以下两种操作:

  1、 查询操作。

  语法:Q L

  功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。

  限制:L不超过当前数列的长度。

  2、 插入操作。

  语法:A n

  功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾。

  限制:n是整数(可能为负数)并且在长整范围内。

  注意:初始时数列是空的,没有一个数。

线段树版

思路:

  先把树开满,没出现的数都设成零,单点修改,区间查询。

代码:

#include <iostream>
#include <cstdio>
using namespace std;
typedef unsigned long long ull;
ull tree[524288],dep;
int firstbit(int n){
int ans=0;
    n--;
    while(n){
        ans++;
        n>>=1;
    }
    return 1<<ans;
}
void update(int w,int n){
    w+=dep;
    tree[w]+=n;
    for(w>>=1;w;w>>=1)
        tree[w]=max(tree[w<<1],tree[w<<1|1]);
}
ull query(int l,int r){
ull ans=0;
    for(int lc=l+dep-1,rc=r+dep+1;lc^rc^1;lc>>=1,rc>>=1){
        if(~lc&1)
            ans=max(ans,tree[lc^1]);
        if( rc&1)
            ans=max(ans,tree[rc^1]);
    }
    return ans;
}
int main(){
int t=0,w=1,M,D;
    ios::sync_with_stdio(false);
    cin>>M>>D;
    dep=firstbit(200005);
    while(M--){
        char c;
        cin>>c;
        if(c==‘A‘){
            int n;
            cin>>n;
            update(w,(t+n)%D);
            w++;
        }
        else{
            int n;
            cin>>n;
            t=query(w-n,w-1)%D;
            cout<<t<<endl;
        }
    }
    return 0;
}

  

单调栈版

思路:

  用单调栈维护最大值,在栈中二分查找答案。

代码:

 

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
struct Node{
	int no;
	ull n;
};
bool cmp(Node a,Node b){
	return a.no<b.no;
}
Node s[200005];
int main(){
int t=0,top=-1,D,M,w=1;
	ios::sync_with_stdio(false);
	cin>>M>>D;
	while(M--){
		char c;
		cin>>c;
		if(c==‘A‘){
			int tem,n;
			cin>>n;
			tem=(t+n)%D;
			while(~top&&s[top].n<tem)
				top--;
			top++;
			s[top].n=tem;
			s[top].no=w++;
		}
		else {
			int whe;
			Node n;
			cin>>n.no;
			n.no=w-n.no;
			whe=lower_bound(s,s+top+1,n,cmp)-s;
			t=s[whe].n;
			cout<<t<<endl;
		}
	}
	return 0;
}

 

  

 

JSOI2008 最大数

标签:stream   oid   个数   负数   ora   font   nbsp   查询   first   

原文地址:http://www.cnblogs.com/HC-LittleJian/p/7753353.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!