I don't want to talk nonsense in this article.
Q: Fixed K, dynamic addition, and dynamic query of the K number.
I. Tree array + binary
There are two methods: Binary sum (I) and binary sum (k.
Tree arrays are often used to process the statistics of interval points. Here N has no specified size (theoretically int32), but the number of operations N is less than 1000,000, so we can first discretization to store 1000,000 vertex values (I don't know if this is called discretization, because the vertex itself is an integer,, this is at least a hash and a ing ).
The specific operation is to first read all the points in the sample and then sort them, insert (lower_bound (list, list + n, a [I])-list + 1 ). A [] is the original sequence, and list is the sorted sequence. + 1 is used to avoid the subscript being 0. Now the discretization is complete.
Returns the maximum K Number:
① Binary sum (I), using the binary search idea, the target is tot-sum (ANS) <k <= tot-sum (ans-1 ). Sum () is the sum operation of the tree array. Note that C [x] In the tree Array records the weight of X, that is, the number of C [x] records is the same as X, it is not necessarily true when we look for the k-th large number. We cannot look for it in the original binary mode. Here we have wa many times ......
② Binary bipartite approximation, inspired by the following two ideas,
Http://tieba.baidu.com/F? Kz= 1033300126
Http://www.cnblogs.com/zgmf_x20a/archive/2008/11/15/1334109.html
It is used to calculate the decimal number of K. Obviously, when the total number of points is known, it can be used to obtain the large number of K.
But later I found that the first version was wrong,
Similar code
int ans=0;for(int i=1<<log2(all); i; i>>=1){if(c[ans+i] <= k){k-=c[ans+=i];}}return ans;
I have been using this wa for a long time, and there are two errors: ① change to If (C [ans + I] <K), and finally return ans + 1. The reason is the same as the red letter. ② Add ans + I to If <all &&...
Code (for the combination of the two methods, see the Notes ):
// Hdoj-4006, dynamic k Number # include <cstdio> # include <cstring> # include <iostream> # include <algorithm> using namespace STD; # define maxn 1000005 # define lowbit (x) X & (-x) int A [maxn]; // original array, up to 1000000 int list [maxn]; // sorting sequence int Q [maxn]; // whether to query: qint C [maxn]; int N, K, all; int log2 (int x) {int I = 0; for (; X; x> = 1, I ++); Return I-1;} void insert (INT X) {While (x <= All) {c [x] + = 1; x + = lowbit (x );}} /// // Method I. binary, binary approaching int find_kth_small (int K) {int ans = 0; For (INT I = 1 <log2 (all); I >>= 1) {If (ANS + I <all & C [ans + I] <k )//!!! {K-= C [ans + = I] ;}} return ans + 1;/* // int CNT = 0, ANS = 0; for (INT I = 1 <log2 (all); I >>= 1) {ans + = I; if (ANS> = All | CNT + C [ANS]> = k) ans-= I; else CNT + = C [ANS];} return ans + 1; */} int find_kth_great (int K, int ToT) {return find_kth_small (TOT-k + 1 );} /// // Method 2: Binary sum (I) int sum (int I) {int res = 0; For (; I> 0; I-= lowbit (I) {res + = C [I];} return res;} int search (int K )//!! The target is tot-sum (ANS) <k <= tot-sum (ans-1), while the common binary search target is k = A [ANS]. {int L = 1, R = All; int tot = sum (r); While (L <= r) {int mid = (L + r)/2; if (TOT-sum (MID)> = k) {L = Mid + 1;} else if (TOT-sum (MID) <K & K <= tot-sum (mid-1) {return mid;} else {r = mid-1 ;}/ * // This is also true, but I think the above is a good understanding. While (L <= r) {int mid = (L + r)/2; If (TOT-sum (mid-1)> = K) L = Mid + 1; else r = mid-1;} return L-1; */} int main () {While (CIN> N> K) {memset (C, 0, sizeof (c); memset (Q, 0, sizeof (q); All = 0; // The total number of records added for (INT I = 0; I <n; I ++) {char T [2]; CIN> T; If (T [0] = 'I') {int X; CIN> X; A [I] = X; // A [] original sequence list [All ++] = x; // The added sequence, which must be sorted, convenience hash} else if (T [0] = 'q') {q [I] = 1 ;}} sort (list, list + ALL ); int tot = 0; For (INT I = 0; I <n; I ++) {If (! Q [I]) {tot ++; insert (lower_bound (list, list + ALL, a [I])-list + 1); // + 1, avoid 0 subscript} else {// cout <list [search (k)-1] <Endl; // first, binary binary approximation cout <list [find_kth_great (K, TOT)-1] <Endl; // second, binary sum (I )}}}}
2. Heap Building
Create a small top heap and put k elements. Insert a number each. If this number is greater than the heap top, the heap is inserted and the original heap top is removed. If this number is smaller than the heap top, the operation is not performed because there is no impact. This makes use of the particularity of this question, that is, K is fixed in one example, unlike other questions that may input "Q k" as an instruction. This makes the first question of this game. (Hide your face .....)
As we all know, priority_queue is implemented using a binary heap. The version of STL priority queue is given below:
# Include <iostream> # include <queue> # include <vector> using namespace STD; struct CMP {bool operator () (int A, int B) {return a <B? 0: 1 ;}}; priority_queue <int, vector <int>, CMP> q; // or directly, greater <int> int N, K; int main () {While (CIN> N> K) {While (n --) {char T [2]; CIN> T; if (T [0] = 'I') {int X; CIN> X; If (Q. size () <k) Q. push (x); else if (x> q. top () {q. pop (); q. push (x) ;}} else {cout <q. top () <Endl ;}}}}