The moment to kill this problem, I just want to say: I finally * * * AC!!!
The final memory 1344K, time-consuming 10282ms, compared to the merging tree, partition tree and other various black technology, this result is not a glorious ⊙﹏⊙
But at least, from the initial countless tle to the final AC, this process witnessed the arduous optimization of a binary algorithm
Paste the code First:
1 Const intBktsize=1024x768;2 Const intbktmaxidx=bktsize-1;3 Const intBktcount= -;4 Const intbktdigit=Ten;5 Const intmaxv=1e9;6 7 intBucket[bktcount][bktsize];8 intunordered[bktsize*Bktcount];9 intordered[bktsize*Bktcount];Ten intn,k; One A#include <cstdio> -#include <cstring> -#include <algorithm> the - voidInit () - { -scanf"%d%d",&n,&K); +memset (Bucket[n>>bktdigit],0x7f,sizeof(bucket[n>>Bktdigit])); - for(intI=0; i<n;i++) + { Ascanf"%d", unordered+i); atordered[i]=Unordered[i]; -bucket[i>>bktdigit][i&bktmaxidx]=Unordered[i]; - } - - usingStd::sort; - intBktused=n>>Bktdigit; inSort (ordered,ordered+N); - for(intI=0; i<=bktused;i++) Sort (bucket[i],bucket[i]+bktsize); to } + -InlinevoidEnumerate (int_rangel,int_ranger,int_val,int&_notmore) the { * for(inti=_rangel;i<=_ranger;i++) $ if(unordered[i]<=_val) + +_notmore;Panax Notoginseng } - theInlinevoidCountbucket (int_bktidx,int_val,int&_notmore) + { A usingStd::upper_bound; the + int* Ub=upper_bound (bucket[_bktidx],bucket[_bktidx]+bktsize,_val); -_notmore+= (ub-Bucket[_bktidx]); $ } $ - intAskint_rangel,int_ranger,int_K)//k-th Smallest - { the intDigitl=_rangel>>Bktdigit; - intDigitr=_ranger>>Bktdigit;Wuyi intVl=0; the intvr=n-1; - Wu while(vl<VR) - { About intmidv= (VL+VR) >>1; $ intNotmore=0; - if(digitl==Digitr) - Enumerate (_rangel,_ranger,ordered[midv],notmore); - Else A { + for(inti=digitl+1; i<digitr;i++) the Countbucket (i,ordered[midv],notmore); -Enumerate (_rangel, (digitl+1) <<bktdigit)-1, Ordered[midv],notmore); $Enumerate (digitr<<bktdigit,_ranger,ordered[midv],notmore); the } the the if(Notmore<_k) vl=midv+1; the ElseVr=Midv; - } in returnORDERED[VL]; the } the About intMain () the { the init (); the for(intI=0; i<k;i++) + { - intl,r,k; thescanf"%d%d%d",&l,&r,&k);Bayiprintf"%d\n", Ask (l1, R-1, K)); the } the return 0; -}
View Code
1, why statistics Notmore, not statistics less or both statistics?
In the two-point process, the key to the reduction interval is:
1. The value that may be the final solution must be kept in a two-minute interval
2, each time must make the interval size is indeed reduced, in order to prevent into a dead cycle
In this problem, a value of x is the solution condition: less (x) <x && notmore (x) >=x
If statistics less, the above code is difficult to guarantee the first article
And if both are counted, the surface can jump out when the x meets the conditions, reducing the time required for two points.
But in fact, the cost of doing this is to multiply the statistical time complexity constant by 2, which is generally not worth the candle (tle)
2, what is the object of the two points? Can maxvalue and minvalue be used as two-point objects?
answer:no!!!
The correct approach is to sequence the original array and then divide the ordered array by two.
The reason is simple: the range is small. The two-point interval will not exceed 1e5
If the value itself is divided into two, the worst of MinValue and MaxValue will be -1e9 and +1e9 respectively, the second time cost is 1.9 times times the former
3, the square partition must be strict?
Answer:no (*^__^*)
Set the data size to N, the size of each bucket is B, the time complexity of a single query is: O ((n/b) * Log B + b)
When B = O ((n * log n) ^ 0.5), the total time complexity is smaller than the strict square segment
This is why the code takes B for 1024. (By the way also convenient bit operation)
b When taking 512, the efficiency will be relatively poor, b take 256 when simply tle
The better way to do this is to merge the tree, better than the merger tree is divided into trees, but this is something, there is time to slowly pits
POJ2104 k-th number static interval K-Max squared Division