[JSOI2008]最大数maxnumber

[JSOI2008]最大数maxnumberTime Limit: 3 Sec  Memory Limit: 162 MB
Submit: 6471  Solved: 2756
[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

HINT

Source

                        [Submit][Status][Discuss]

  线段树求区间最值,如果能动态开点就更好了。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<cstring>
 7 #include<vector>
 8 #include<queue>
 9 using namespace std;
10 typedef long long LL;
11 const LL maxn=200005;
12 const LL inf=1e15;
13 inline LL read(){
14     LL x=0,f=1;char ch=getchar();
15     while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
16     while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
17     return x*f;
18 }
19 LL N,M,D;
20 LL tot=1;
21 LL a[maxn];
22 LL NOW;
23 char c[10];
24 LL P;
25 struct node{
26     LL num;
27     LL MAX;
28     LL l,r,lc,rc;
29 }seg[maxn*8];
30 inline void Build(LL root,LL l,LL r){
31     seg[root].num=tot;
32     seg[root].l=l; seg[root].r=r;
33     if(seg[root].l==seg[root].r){
34         seg[root].MAX=a[l];
35         return;
36     }
37     LL mid=(seg[root].l+seg[root].r)>>1;
38     seg[root].lc=++tot; Build(tot,l,mid);
39     seg[root].rc=++tot; Build(tot,mid+1,r);
40     seg[root].MAX=max(seg[seg[root].lc].MAX,seg[seg[root].rc].MAX);
41 }
42 inline LL query(LL root,LL l,LL r){
43     if(l<=seg[root].l&&seg[root].r<=r){
44         return seg[root].MAX;
45     }
46     LL mid=(seg[root].l+seg[root].r)>>1;
47     LL ans=-inf;
48     if(l<=mid) ans=max(ans,query(seg[root].lc,l,r));
49     if(mid+1<=r) ans=max(ans,query(seg[root].rc,l,r));
50     seg[root].MAX=max(seg[seg[root].lc].MAX,seg[seg[root].rc].MAX);
51     return ans;
52 }
53 inline void change(LL root,LL l,LL r,LL delta){
54     if(l<=seg[root].l&&seg[root].r<=r){
55         seg[root].MAX=delta;
56         return ;
57     }
58     LL mid=(seg[root].l+seg[root].r)>>1;
59     if(l<=mid) change(seg[root].lc,l,r,delta);
60     if(mid+1<=r) change(seg[root].rc,l,r,delta);
61     seg[root].MAX=max(seg[seg[root].lc].MAX,seg[seg[root].rc].MAX);
62 }
63 int main(){
64     scanf("%lld%lld",&M,&D);
65     for(int i=1;i<=M;i++) a[i]=-inf;
66     Build(1,1,M);
67     for(LL i=1;i<=M;i++){
68         scanf("%s",c);
69         if(c[0]==‘A‘){
70             scanf("%lld",&P);
71             P=(P+NOW)%D;
72             N++;
73             change(1,N,N,P);
74         }
75         else{
76             scanf("%lld",&P);
77             NOW=query(1,N-P+1,N);
78             printf("%lld\n",NOW);
79         }
80     }
81     return 0;
82 }
时间: 2024-10-05 18:19:43

[JSOI2008]最大数maxnumber的相关文章

BZOJ 1012: [JSOI2008]最大数maxnumber(线段树)

012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MB Description 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2. 插入操作.语法:A n 功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列

bzoj-1012 1012: [JSOI2008]最大数maxnumber(线段树)

题目链接: 1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MB Description 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2. 插入操作.语法:A n 功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得

BZOJ 1012: [JSOI2008]最大数maxnumber(线段树)

裸的线段树...因为数组开小了而一直RE..浪费了好多时间.. -------------------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<cstring> #include<cctype> #include<iostream> #define rep(i,n) for(int i=

BZOJ 1012: [JSOI2008]最大数maxnumber 单调栈

单调栈 1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MB Submit: 4988  Solved: 2252 [Submit][Status][Discuss] Description 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度. 2. 插入操作.语法:A n 功能:将n加上t,其中

1012: [JSOI2008]最大数maxnumber

1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 4435  Solved: 2000[Submit][Status] Description 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度. 2. 插入操作.语法:A n 功能:将n加上t,其中t是最近一次查询操作的答案(如

单调栈 BZOJ1012 [JSOI2008]最大数maxnumber

1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 10440  Solved: 4571[Submit][Status][Discuss] Description 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数列中末尾L 个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2. 插入操作.语法:A n 功能:将n加 上t,其中t是最近一

【bzoj1012】[JSOI2008]最大数maxnumber

1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 8339  Solved: 3624[Submit][Status][Discuss] Description 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2. 插入操作.语法:A n 功能:将n加上t,其中t是最近一次查询

BZOJ 1012: [JSOI2008]最大数maxnumber 单调队列/线段树/树状数组/乱搞

1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 4750  Solved: 2145[Submit][Status][Discuss] Description 现 在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度. 2. 插入操作.语法:A n 功能:将n加上t,其中t是最近一

[JSOI2008]最大数maxnumber(栈&amp;二分查找)

题目链接:1012: [JSOI2008]最大数maxnumber 题意 中文题,点链接看吧,就不copy了. 思路 打眼一看立刻就想到线段树,但本题的区间最值查找每次都是在查后L位,感觉用线段树有些大材小用了. 再仔细想想,发现,如果倒数第i个比倒数第i+1个数小,那么第i个数是没有用的,任意查询的最值都不会是它,因为查的是后L个嘛. 所以呢,我们我以维护一个栈,每次添加新元素时,将其与栈顶元素比较,若栈顶元素小,即无用了,那就出栈,否则,就将新元素入栈. 在查询时直接对栈里元素进行二分查找就

【BZOJ】1012: [JSOI2008]最大数maxnumber(树状数组+区间最值)

http://www.lydsy.com/JudgeOnline/problem.php?id=1012 树状数组原来我只懂得sum和add的操作,今天才知道可以有求区间最值的操作,我学习了一下写了个,1a了. 区间最值其实和区间求和差不多,就是将sum数组的含义转移到max,然后通过特定的区间更新max. 在区间求和中,当我们维护max[i]的时候,要找到它前面所有的max[j]来更新,在这里因为是树状数组,所以可以降成一个log级,画图可知,max[i]需要的max只有max[i-2^0],