生活随笔
收集整理的這篇文章主要介紹了
2019蓝桥杯国赛B组第九题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目描述: 有一條河,沿河的一側生活著一個部落。這個一字型的部落有n個據點,從左至右依次編號1~n。 部落的人們有時會在某個據點建立建筑,每個建筑都有各自的價值。一開始,每個據點的都沒有建筑,價值都是0。如果在已有建筑的據點建立新的建筑,那么新的建筑會代替舊的建筑(舊的建筑就此消失)。 有兩種操作C和Q: 1、C x y,表示在據點x建立一個價值為y的建筑。 2、Q x y,詢問在據點x~y之間(包括x,y)的建筑中,價值第八大的建筑的價值是多少。
輸入描述: 第一行,兩個正整數n和k,表示據點的數量和操作的數量。 接下的k行,每行一個操作。
輸出描述: 對于所有的Q操作,輸出相應的第八大建筑的價值。
輸入樣例: 10 14 C 1 5 C 2 4 C 3 7 C 4 6 C 5 5 C 6 1 C 7 8 Q 1 10 C 8 3 C 9 6 C 10 3 Q 1 9 C 6 10 Q 1 10
輸出樣例: 0 3 4 思路:唉,當時要是能想到這一點,也不會只拿個國二了。 很明顯,區間操作,線段樹是很容易想到的。但是這次線段樹的每一個節點不是維護一個數了,而是8個數。因為8很小,所以還是可以承擔的。每次pushup的時候,將最大的八個數更新給父節點。查詢的時候返回一個數組就可以了。代碼沒有測試,不知道有沒有問題,當個參考吧。 代碼如下:
#include <bits/stdc++.h>
#define ll long long
using namespace std
; const int maxx
= 1e5 + 100 ;
struct node
{ int l
; int r
; int a
[ 9 ] ; int len
;
} p
[ maxx
<< 2 ] ;
int n
, m
, x
, y
; inline void pushup ( int cur
)
{ int * c1
= new int [ 9 ] ; int * c2
= new int [ 9 ] ; int len1
= p
[ cur
<< 1 ] . len
; int len2
= p
[ cur
<< 1 | 1 ] . len
; sort ( p
[ cur
<< 1 ] . a
, p
[ cur
<< 1 ] . a
+ len1
) ; sort ( p
[ cur
<< 1 | 1 ] . a
, p
[ cur
<< 1 | 1 ] . a
+ len2
) ; c1
= p
[ cur
<< 1 ] . a
; c2
= p
[ cur
<< 1 | 1 ] . a
; int len
= 0 ; len1
-- , len2
-- ; while ( len
< 8 && ( len1
>= 0 && len2
>= 0 ) ) { if ( c1
[ len1
] > c2
[ len2
] ) p
[ cur
] . a
[ len
++ ] = c1
[ len1
] , len1
-- ; else p
[ cur
] . a
[ len
++ ] = c2
[ len2
] , len2
-- ; } if ( len1
== - 1 ) while ( len
< 8 && len2
>= 0 ) p
[ cur
] . a
[ len
++ ] = c2
[ len2
-- ] ; else while ( len
< 8 && len1
>= 0 ) p
[ cur
] . a
[ len
++ ] = c1
[ len1
-- ] ; while ( len
< 8 ) p
[ cur
] . a
[ len
++ ] = 0 ; p
[ cur
] . len
= len
;
}
inline void build ( int l
, int r
, int cur
)
{ p
[ cur
] . l
= l
; p
[ cur
] . r
= r
; p
[ cur
] . len
= 0 ; memset ( p
[ cur
] . a
, 0 , sizeof ( p
[ cur
] . a
) ) ; if ( l
== r
) return ; int mid
= l
+ r
>> 1 ; build ( l
, mid
, cur
<< 1 ) ; build ( mid
+ 1 , r
, cur
<< 1 | 1 ) ;
}
inline void update ( int pos
, int v
, int cur
)
{ int L
= p
[ cur
] . l
; int R
= p
[ cur
] . r
; if ( L
== R
) { p
[ cur
] . a
[ 0 ] = v
; p
[ cur
] . len
= 1 ; return ; } int mid
= L
+ R
>> 1 ; if ( pos
<= mid
) update ( pos
, v
, cur
<< 1 ) ; else update ( pos
, v
, cur
<< 1 | 1 ) ; pushup ( cur
) ;
}
inline int * query ( int l
, int r
, int cur
)
{ int L
= p
[ cur
] . l
; int R
= p
[ cur
] . r
; if ( l
<= L
&& R
<= r
) return p
[ cur
] . a
; int mid
= L
+ R
>> 1 ; if ( r
<= mid
) return query ( l
, r
, cur
<< 1 ) ; else if ( l
> mid
) return query ( l
, r
, cur
<< 1 | 1 ) ; else { int * c1
= new int [ 9 ] ; c1
= query ( l
, mid
, cur
<< 1 ) ; int * c2
= new int [ 9 ] ; c2
= query ( mid
+ 1 , r
, cur
<< 1 | 1 ) ; sort ( c1
, c1
+ 8 ) ; sort ( c2
, c2
+ 8 ) ; int * c
= new int [ 9 ] ; int len
= 0 , len1
= 7 , len2
= 7 ; while ( len
< 8 && ( len1
>= 0 && len2
>= 0 ) ) { if ( c1
[ len1
] > c2
[ len2
] ) c
[ len
++ ] = c1
[ len1
] , len1
-- ; else c
[ len
++ ] = c2
[ len2
] , len2
-- ; } if ( len1
== - 1 ) while ( len
< 8 && len2
>= 0 ) c
[ len
++ ] = c2
[ len2
-- ] ; else while ( len
< 8 && len1
>= 0 ) c
[ len
++ ] = c1
[ len1
-- ] ; return c
; }
}
int main ( )
{ scanf ( "%d%d" , & n
, & m
) ; build ( 1 , n
, 1 ) ; char s
[ 2 ] ; while ( m
-- ) { scanf ( "%s%d%d" , s
, & x
, & y
) ; if ( s
[ 0 ] == 'C' ) update ( x
, y
, 1 ) ; else { int * c
= new int [ 9 ] ; c
= query ( x
, y
, 1 ) ; sort ( c
, c
+ 8 ) ; printf ( "%d\n" , c
[ 0 ] ) ; } } return 0 ;
}
努力加油a啊,(o )/~
總結
以上是生活随笔 為你收集整理的2019蓝桥杯国赛B组第九题 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。