Original posts: http://www.cnblogs.com/zgmf_x20a/archive/2008/11/15/1334109.html
Recalling the definition of a tree array, note the following two properties:
One, c[ans]=sum of a[ans-lowbit (ans) +1 ... ans];
Second, when Ans=2^k,
C[ans]=sum of a[1 ... ans];
The following shows how Findk (k) Works:
1, set the boundary condition Ans,ans ' <maxn and cnt<=k;
2, initialize Cnt=c[ans], where ans=2^k and K are the largest integers that satisfy the boundary conditions;
3. Find the largest ans ' that satisfies the boundary conditions ' so that ans '-lowbit (ans ') =ans, i.e. ans ' satisfies c[ans ']=a[ans+1. Ans '] (according to the nature of one), as long as the C[ans '] is added to CNT (at this time cnt=sum of a[ 1 ... ans '], according to the nature of the second), CNT can be used as the approximate value of k;
4, repeat the 3rd step until CNT can no longer approximate k, when ans is just 1 smaller than the solution, return to ans+1.
So the essence of FINDK (k) is the approximation of two points
1 /**********************************2 3 tree-like array to find elements of K-small4 5 Classic. 6 7 limit: Data range within 1<<208 9 ***********************************/Ten One#include <iostream> A - using namespacestd; - the - - #defineMAXN 1<<20 - + intn,k; - + intC[MAXN]; A at - - intLowbit (intx) { - - returnx&-x; - in } - to + - voidInsertintXintt) { the * while(x<MAXN) { $ Panax Notoginsengc[x]+=T; - thex+=lowbit (x); + A } the + } - $ intFindintk) { $ - intCnt=0, ans=0; - the for(intI= -; i>=0; i--){ - Wuyians+= (1<<i); the - if(ANS>=MAXN | | cnt+c[ans]>=k) ans-= (1<<i); Wu - Elsecnt+=C[ans]; About $ } - - returnans+1; - A } + the voidinput () { - $Memset (c,0,sizeof(c)); the the intT; the thescanf"%d%d",&n,&k); - in for(intI=0; i<n;i++){ the thescanf"%d",&t); About theInsert (T,1); the the } + -printf"%d\n", find (k)); the Bayi } the the intMain () { - - intcases; the thescanf"%d",&cases); the the while(cases--){ - the input (); the the }94 the return 0; the the}View Code
"Reprint" "Tree array interval k big/small"