Original title Link: http://acm.hdu.edu.cn/showproblem.php?pid=4417
Test instructions is very simple, given a sequence to find the number of elements in an interval [L, R,] less than or equal to H.
As if the function of the line segment tree can be solved, but weak weak satay has not been able to understand its essence, had to use tree set of tree violence crushed
The forehead tree sets the tree, and each node of the line tree sets a SB-tree.
When the value in the query [L,r] interval is less than or equal to the number of H, the corresponding interval is first found with the segment tree.
Then query the interval under the corresponding balance tree is less than or equal to the number of H, accumulate.
Always thought it would time out, the result 400+ms, the data should be very weak bar (self-patted a group (n,m) 10w-scale run 2s more o (╯-╰) o).
1#include <cstdio>2#include <cstdlib>3#include <cstring>4#include <algorithm>5 #defineLC Root<<16 #defineRC Root<<1|17 Const intMax_n =100100; 8 structsbt{9 intV, S, c; TenSBT *ch[2]; OneInlinevoid Set(int_v =0){ Av = _v, c = s =1; -ch[0] = ch[1] =NULL; - } theInlinevoidpush_up () { -s = ch[0]->s + ch[1]->s +C; - } -InlineintcmpintXConst{ + returnv = = x? -1: x >v; - } +}*NULL, Stack[max_n <<3], *ptr[max_n <<2]; A intSZ =0, sum =0, Arr[max_n]; at voidinit () { - NULL= &stack[sz++]; - NULL->v =NULL->s =NULL->c =0; - } -InlinevoidRotate (sbt* &x,intd) { -SBT *k = x->ch[!d]; inX->CH[!D] = k->Ch[d]; -K->CH[D] =x; toK->s = x->s;; +X->push_up (); -x =K; the } * voidMaintain (sbt* &x,intd) { $ if(X->ch[d] = =NULL)return; Panax Notoginseng if(X->ch[d]->ch[d]->s > x->ch[!d]->s) { -Rotate (x,!d); the}Else if(X->ch[d]->ch[!d]->s > x->ch[d]->s) { +Rotate (x->ch[d], D), rotate (x,!d); A}Else { the return; + } -Maintain (x,0), Maintain (x,1); $ } $ voidInsert (sbt* &x,intv) { - if(x = =NULL){ -x = &stack[sz++]; theX->Set(v); -}Else { Wuyix->s++; the intD = x->CMP (v); - if(-1==d) { WuX->c++; - return; About } $Insert (x->Ch[d], V); -X->push_up (); - Maintain (x, d); - } A } + intSbt_rank (SBT *x,intkey) { the intT, cur; - for(t = cur =0; X! =NULL;){ $t = x->ch[0]->s; the if(Key < x->v) x = x->ch[0]; the Else if(Key >= x->v) cur + = x->c + T, x = x->ch[1]; the } the returncur; - } in voidSeg_built (intRootintLintR) { thePtr[root] =NULL; the for(inti = l; I <= R; i++) Insert (Ptr[root], arr[i]); About if(L = = r)return; the intMid = (L + r) >>1; the seg_built (LC, L, mid); theSeg_built (RC, Mid +1, R); + } - voidSeg_rank (intRootintLintRintXintYintv) { the if(X > R | | y < L)return; Bayi if(x <= l && y >=R) { theSum + =Sbt_rank (Ptr[root], V); the return; - } - intMid = (L + r) >>1; the Seg_rank (LC, L, Mid, X, Y, v); theSeg_rank (RC, Mid +1, R, X, Y, v); the } the intMain () { - #ifdef LOCAL theFreopen ("In.txt","R", stdin); theFreopen ("OUT.txt","w+", stdout); the #endif 94 intI, T, N, M, A, B, c, k =1; thescanf"%d", &t); the while(t--){ theSZ =0, Init (); 98scanf"%d%d", &n, &m); Aboutprintf"Case %d:\n", k++); - for(i =1; I <= N; i++) scanf ("%d", &Arr[i]); 101Seg_built (1,1, N); 102 while(m--){ 103scanf" %d%d%d", &a, &b, &c); 104sum =0; theSeg_rank (1,1, N, A +1, B +1, c); 106printf"%d\n", sum); 107 } 108 } 109 return 0; the}
View Code
HDU 4417 Super mario/Tree Set