Luogu P1533 可怜的狗狗
题目链接:https://www.luogu.org/problemnew/show/P1533
没人写$fhq\ treap$做法,那我就补一篇qwq
看到这题第一时间想主席树,然后发现我还没学主席树,于是就写了平衡树做法(当然树状数组+二分的套路也是可以的,但是两个$log$的复杂度太优秀了就不写了)
其实和treap的写法差不多,也是排序一遍然后插入,删除,求$kth$
不过好写很多,主体就40+行,注意一开始那个节点的值一定要大...
我开$0x3f$然后挂了一个上午...
(其实一开始还写了莫队来着但是发现不需要)
#include <bits/stdc++.h> #define ll long long #define inf 0x7fffffff #define il inline namespace io { #define in(a) a=read() #define out(a) write(a) #define outn(a) out(a),putchar('\n') #define I_int int inline I_int read() { I_int x = 0 , f = 1 ; char c = getchar() ; while( c < '0' || c > '9' ) { if( c == '-' ) f = -1 ; c = getchar() ; } while( c >= '0' && c <= '9' ) { x = x * 10 + c - '0' ; c = getchar() ; } return x * f ; } char F[ 200 ] ; inline void write( I_int x ) { if( x == 0 ) { putchar( '0' ) ; return ; } I_int tmp = x > 0 ? x : -x ; if( x < 0 ) putchar( '-' ) ; int cnt = 0 ; while( tmp > 0 ) { F[ cnt ++ ] = tmp % 10 + '0' ; tmp /= 10 ; } while( cnt > 0 ) putchar( F[ -- cnt ] ) ; } #undef I_int } using namespace io ; using namespace std ; #define N 300010 #define int long long int n , tot = 0, root = 1; //fhq-treap struct fhq_treap { int siz , val , lc , rc , rnk ; } t[N] ; void pushup(int rt) {t[rt].siz = t[t[rt].lc].siz + t[t[rt].rc].siz + 1 ;} void split(int &a , int &b , int val , int rt) { if(!rt) { a = b = 0 ; return ; } if(t[rt].val <= val) a = rt , split(t[a].rc , b , val , t[rt].rc) ; else b = rt , split(a , t[b].lc , val , t[rt].lc) ; pushup(rt) ; } void merge(int a , int b , int &rt) { if(!a || !b) {rt = a + b ; return ;} if(t[a].rnk < t[b].rnk) rt = a , merge(t[a].rc , b , t[rt].rc) ; else rt = b , merge(a , t[b].lc , t[rt].lc) ; pushup(rt) ; } int new_node(int val) { t[++tot] = (fhq_treap) {1 , val , 0 , 0 , rand()} ; return tot ; } inline void insert(int val) { int x = 0 , y = 0 , z = new_node(val) ; split(x , y , val , root) ; merge(x , z , x) ; merge(x , y , root) ; } void Del(int val) { int x = 0 , y = 0 , z = 0 ; split(x , y , val , root) ; split(x , z , val - 1 , x) ; merge(t[z].lc , t[z].rc , z) ; merge(x , z , x) ; merge(x , y , root) ; } inline int find_val(int rnk , int rt) { while(t[t[rt].lc].siz + 1 != rnk) { if(t[t[rt].lc].siz >= rnk) rt = t[rt].lc ; else rnk -= t[t[rt].lc].siz + 1 , rt = t[rt].rc ; } return t[rt].val ; } //fhq-treap end struct query { int l , r , val , id; } q[N] ; int ans[N] , a[N] , block ; bool cmp(query a , query b) { return a.l == b.l ? a.r < b.r : a.l < b.l ; } signed main() { #ifndef ONLINE_JUDGE freopen("1.in","r",stdin); freopen("1.out","w",stdout); #endif srand((unsigned)time(0)) ; n = read() ; int m = read() ; new_node(inf) ; t[1].siz = 0 ; for(int i = 1 ; i <= n ; i ++) a[i] = read() ; for(int i = 1 ; i <= m ; i ++) q[i] = (query) {read() , read() , read() , i} ; block = sqrt(n) ; sort(q + 1 , q + m + 1 , cmp) ; q[0].l = 1 ; for(int i = 1 ; i <= m ; i ++) { for(int cur = q[i-1].r + 1 ; cur <= q[i].r ; cur ++) insert(a[cur]) ; for(int cur = q[i-1].l ; cur < q[i].l ; cur ++) Del(a[cur]) ; ans[q[i].id] = find_val(q[i].val , root) ; } for(int i = 1 ; i <= m ; i ++) outn(ans[i]) ; }