BZOJ 1012 题解
1012: [JSOI2008]最大数maxnumber
Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 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
A 96
Q 1
A 97
Q 1
Q 2
Sample Output
96
93
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
(完)