BZOJ 1012 题解

1012: [JSOI2008]最大数maxnumber

Time Limit: 3 Sec  Memory Limit: 162 MB
Submit: 8468  Solved: 3702
[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

Sample Output

96
93
96

Solution

题目中要求边插入,边查询,于是想到用线段树.

 1 /**************************************************************
 2     Problem: 1012
 3     User: shadowland
 4     Language: C++
 5     Result: Accepted
 6     Time:844 ms
 7     Memory:24732 kb
 8 ****************************************************************/
 9
10 #include "bits/stdc++.h"
11
12 using namespace std ;
13 const int maxN = 500100 ;
14 const int INF = 2147483647 ;
15 struct SegTree { int l , r , maxtr ; } ;
16
17 SegTree tr[ maxN << 2 ] ;
18
19 int pos , cnt , last ;
20
21 inline int gmax ( int x , int y ) { return x > y ? x : y ; }
22 inline void Push_up ( const int i ) { tr[ i ].maxtr = gmax ( tr[ i << 1 | 1 ].maxtr , tr[ i << 1 ].maxtr ) ; }
23
24 int INPUT ( ) {
25         int x = 0 , f = 1 ; char ch = getchar ( ) ;
26         while ( ch < ‘0‘ || ch > ‘9‘ ) { if ( ch == ‘-‘ ) f = -1 ; ch = getchar ( ) ; }
27         while ( ch >= ‘0‘ && ch <= ‘9‘ ) { x = ( x << 1 ) + ( x << 3 ) + ch - ‘0‘ ; ch = getchar ( ) ;}
28         return x * f ;
29 }
30
31
32 void Build_Tree ( const int x , const int y , const int i ) {
33         tr[ i ].l = x ; tr[ i ].r = y ;
34         tr[ i ].maxtr = -INF ;
35         if ( x == y ) return ;
36         else {
37                 int mid = ( tr[ i ].l + tr[ i ].r ) >> 1 ;
38                 Build_Tree ( x , mid , i << 1 ) ;
39                 Build_Tree ( mid + 1 , y , i << 1 | 1 ) ;
40                 Push_up ( i ) ;
41         }
42 }
43
44 void Insert ( const int q , const int val , const int i ) {
45         if ( tr[ i ].l == tr[ i ].r && tr[ i ].l == q ) {
46                 tr[ i ].maxtr = val ;
47                 return ;
48         }
49         else {
50                 int mid = ( tr[ i ].l + tr[ i ].r ) >> 1 ;
51                 if ( q > mid ) Insert ( q , val , i << 1 | 1 ) ;
52                 else if ( q <= mid ) Insert ( q , val , i << 1 ) ;
53                 Push_up ( i ) ;
54         }
55 }
56
57 int Query_Tree ( const int q , const int w , const int i ){
58         if ( q <= tr[ i ].l && tr[ i ].r <= w ) {
59                 return tr[ i ].maxtr ;
60         }
61         else {
62                 int mid = ( tr[ i ].l + tr[ i ].r ) >> 1 ;
63                 if ( q > mid ) return Query_Tree ( q , w , i << 1 | 1 ) ;
64                 else if ( w <= mid ) return Query_Tree ( q , w , i << 1 ) ;
65                 else {
66                         return gmax ( Query_Tree ( q , w , i << 1 | 1 ) , Query_Tree ( q , w , i << 1 ) ) ;
67                 }
68         }
69 }
70
71 int main ( ) {
72         int N = INPUT ( ) , MOD = INPUT ( ) ;
73         Build_Tree ( 1 , N , 1 ) ;
74         for ( int i=1 ; i<=N ; ++i ) {
75                 char ch = getchar ( ) ;
76                 if ( ch == ‘A‘ ) {
77                         ++cnt ;
78                         int tmp = ( INPUT ( ) + last ) % MOD ;
79                         Insert ( cnt , tmp , 1 ) ;
80                 }
81                 else if ( ch == ‘Q‘ ) {
82                         last = Query_Tree ( cnt - INPUT ( ) + 1 , cnt , 1 ) ;
83                         printf ( "%d\n" , last ) ;
84                 }
85         }
86         return 0 ;
87 } 

2016-10-14 23:31:51

()

时间: 2024-10-25 05:11:36

BZOJ 1012 题解的相关文章

BZOJ 1012 [JSOI2008]最大数maxnumber

怎么做都可以题..可以用线段树..可以用平衡树..反正有不少方法 个人比较滋磁单调队列+二分查找的写法,常数小代码少易理解. 具体思路就是维护一个单调不上升的单调队列,然后查询就在这个单调队列中二分查找就好啦~ //这道题,可以算是单调队列的一个妙用了 //当然,做法有很多,可以用线段树.平衡树.树状数组等,其中单调队列最巧妙且最简单 //为什么这道题可以使用单调队列呢? //(即队列中存储的序列必定是下标单调并且数值单调) //如果每个结点没有下标优势(早点入队)也没有数值优势(更大),那么显

点分治专题——bzoj 1468 &amp;bzoj 2152 题解

[前言]最近一直在忙着学算法,但是效果似乎不是很好.前段时间的树剖也快忘了= =.树套树没熟练,就开始写主席树了= =.更别说本身就不是很懂的莫比乌斯反演了.~~决定好好复习一下. [点分治的作用]套用SYC大神的话说是:用来解决树上路径点权统计问题. [大致流程] ①找出这颗树的重心. ②统计经过这个重心的答案 ③用重心把树割开 ④对每个"小树"做同样的事 [Q1--重心]其实找重心再进行计算只是为了不被卡链.什么是重心?就是当前树中的一个点K,使得MAX(SON[K])最小.SON

BZOJ 1054题解 BFS暴力求解

BZOJ 1054题解 BFS暴力求解 1054: [HAOI2008]移动玩具 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1884  Solved: 1033[Submit][Status][Discuss] Description 在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动 时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初始的玩具状态移 动到某人

bzoj一句话题解

bzoj一句话题解 by wawawa8 1000 a+b 1001 平面图最小割->对偶图最短路 1002 就是生成树个数,通过基尔霍夫矩阵可以得出递推式 \(f_i=3f_{i-1}-f_{i-2}+2\),然后高精度算一下 1003 令 \(c[i][j]\) 表示从第 \(i\) 天到第 \(j\) 天从 \(1\) 到 \(n\) 不转换路线的最短距离,然后 \(f[i]\) 表示前 \(i\) 天所需要的最小成本,枚举上一次修改路线的位置 \(j\),即 \(f_i=f_j+c[j+

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是最近一

【线段树】【JSOI 2008】【bzoj 1012】最大数maxnumber

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

[BZOJ 1012] [JSOI 2008] 最大数maxnumber

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

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: 最大数maxnumber

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