[BZOJ] 1012: [JSOI2008]最大数maxnumber
1012: [JSOI2008]最大数maxnumber
Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 11499 Solved: 5036
[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如上文中所述,满足D在longint内。接下来
M行,查询操作或者插入操作。
Output
对于每一个询问操作,输出一行。该行只有一个数,即序列中最后L个数的最大数。
Sample Input
5 100
A 96
Q 1
A 97
Q 1
Q 2
A 96
Q 1
A 97
Q 1
Q 2
Sample Output
96
93
96
93
96
HINT
数据如下http://pan.baidu.com/s/1i4JxCH3
Source
Analysis
最多只有 Emmmm 200000个元素,那么直接开一棵 200000 的线段树
注意不能用 cin/cout ,bzoj好像不吃这一套
Code
1 #include<cstdio> 2 #include<iostream> 3 #define maxn 1000000 4 #define lc (rt<<1) 5 #define rc (rt<<1|1) 6 #define mid (L+R)/2 7 #define LL long long 8 using namespace std; 9 10 int m,tail; 11 LL last,mod; 12 13 struct node{ 14 LL maxx; 15 }T[maxn*4]; 16 17 void modify(int rt,int L,int R,int pos,LL val){ 18 // cout << "Gua!"; 19 if(L == R){ T[rt].maxx = val; return; } 20 if(pos <= mid) modify(lc,L,mid,pos,val); 21 else modify(rc,mid+1,R,pos,val); 22 T[rt].maxx = max(T[lc].maxx,T[rc].maxx); 23 } 24 25 LL query(int rt,int L,int R,int qL,int qR){ 26 if(qL <= L && R <= qR) return T[rt].maxx; 27 else{ 28 LL ans = 0; 29 if(qL <= mid) ans = max(ans,query(lc,L,mid,qL,qR)); 30 if(qR > mid) ans = max(ans,query(rc,mid+1,R,qL,qR)); 31 return ans; 32 } 33 } 34 35 void A(){ 36 LL tmp; scanf("%lld",&tmp); tmp = (tmp+last)%mod; 37 // cout << tmp << ' ' << tail+1; 38 modify(1,1,maxn,tail+1,tmp); tail++; 39 } 40 41 void Q(){ 42 int head; scanf("%d",&head); head = tail-head+1; 43 last = query(1,1,maxn,head,tail); printf("%lld\n",last); 44 } 45 46 void work(){ 47 char ctr[10]; scanf("%s",ctr); 48 if(ctr[0] == 'A') A(); 49 else Q(); 50 } 51 52 int main(){ 53 scanf("%d%lld",&m,&mod); 54 55 last = tail = 0; 56 57 for(int i = 1;i <= m;i++) work(); 58 59 return 0; 60 }
转载请注明出处 -- 如有意见欢迎评论