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 } 
View Code

2016-10-14 23:31:51

 ()
 
 
posted @ 2016-10-14 23:32  SHHHS  阅读(198)  评论(0编辑  收藏  举报