#include <iostream>
using namespace std;
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
// Input: Indices Range [l ... r)
// Invariant: A[l] <= key and A[r] > key
int GetRightPosition(int A[], int l, int r, int key) {
int m;
while( r - l > 1 ) {
m = l + (r - l)/2;
if( A[m] <= key )
l = m;
else
r = m;
}
return l;
}
// Input: Indices Range (l ... r]
// Invariant: A[r] >= key and A[l] > key
int GetLeftPosition(int A[], int l, int r, int key) {
int m;
while( r - l > 1 ) {
m = l + (r - l)/2;
if( A[m] >= key )
r = m;
else
l = m;
}
return r;
}
int CountOccurances(int A[], int size, int key) {
// Observe boundary conditions
int left = GetLeftPosition(A, -1, size-1, key);
int right = GetRightPosition(A, 0, size, key);
// What if the element doesn't exists in the array?
// The checks helps to trace that element exists
return (A[left] == key && key == A[right]) ? right - left + 1 : 0;
}
int main() {
int A[] = {1, 1, 2, 2, 2, 2, 3};
int size = ARRAY_SIZE(A);
int key;
key = 1;
cout << CountOccurances(A, size , key) << endl;
key = 2;
cout << CountOccurances(A, size , key) << endl;
key = 3;
cout << CountOccurances(A, size , key) << endl;
// Unsuccessful case
key = 4;
cout << CountOccurances(A, size , key) << endl;
return 0;
}
CiNpbmNsdWRlIDxpb3N0cmVhbT4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCiNkZWZpbmUgQVJSQVlfU0laRShhKSAoc2l6ZW9mKGEpL3NpemVvZihhWzBdKSkKCi8vIElucHV0OiAgICAgICBJbmRpY2VzIFJhbmdlIFtsIC4uLiByKQovLyBJbnZhcmlhbnQ6ICAgQVtsXSA8PSBrZXkgYW5kIEFbcl0gPiBrZXkKaW50IEdldFJpZ2h0UG9zaXRpb24oaW50IEFbXSwgaW50IGwsIGludCByLCBpbnQga2V5KSB7CiAgICBpbnQgbTsKCiAgICB3aGlsZSggciAtIGwgPiAxICkgewogICAgICAgIG0gPSBsICsgKHIgLSBsKS8yOwoKICAgICAgICBpZiggQVttXSA8PSBrZXkgKQogICAgICAgICAgICBsID0gbTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHIgPSBtOwogICAgfQoKICAgIHJldHVybiBsOwp9CgovLyBJbnB1dDogICAgICAgSW5kaWNlcyBSYW5nZSAobCAuLi4gcl0KLy8gSW52YXJpYW50OiAgIEFbcl0gPj0ga2V5IGFuZCBBW2xdID4ga2V5CmludCBHZXRMZWZ0UG9zaXRpb24oaW50IEFbXSwgaW50IGwsIGludCByLCBpbnQga2V5KSB7CiAgICBpbnQgbTsKCiAgICB3aGlsZSggciAtIGwgPiAxICkgewogICAgICAgIG0gPSBsICsgKHIgLSBsKS8yOwoKICAgICAgICBpZiggQVttXSA+PSBrZXkgKQogICAgICAgICAgICByID0gbTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGwgPSBtOwogICAgfQoKICAgIHJldHVybiByOwp9CgppbnQgQ291bnRPY2N1cmFuY2VzKGludCBBW10sIGludCBzaXplLCBpbnQga2V5KSB7CiAgICAvLyBPYnNlcnZlIGJvdW5kYXJ5IGNvbmRpdGlvbnMKICAgIGludCBsZWZ0ICA9IEdldExlZnRQb3NpdGlvbihBLCAtMSwgc2l6ZS0xLCBrZXkpOwogICAgaW50IHJpZ2h0ID0gR2V0UmlnaHRQb3NpdGlvbihBLCAwLCBzaXplLCBrZXkpOwoKICAgIC8vIFdoYXQgaWYgdGhlIGVsZW1lbnQgZG9lc24ndCBleGlzdHMgaW4gdGhlIGFycmF5PwogICAgLy8gVGhlIGNoZWNrcyBoZWxwcyB0byB0cmFjZSB0aGF0IGVsZW1lbnQgZXhpc3RzCiAgICByZXR1cm4gKEFbbGVmdF0gPT0ga2V5ICYmIGtleSA9PSBBW3JpZ2h0XSkgPyByaWdodCAtIGxlZnQgKyAxIDogMDsKfQoKaW50IG1haW4oKSB7CiAgICBpbnQgQVtdID0gezEsIDEsIDIsIDIsIDIsIDIsIDN9OwogICAgaW50IHNpemUgPSBBUlJBWV9TSVpFKEEpOwogICAgCiAgICBpbnQga2V5OwoKICAgIGtleSA9IDE7CiAgICBjb3V0IDw8IENvdW50T2NjdXJhbmNlcyhBLCBzaXplICwga2V5KSA8PCBlbmRsOwoKICAgIGtleSA9IDI7CiAgICBjb3V0IDw8IENvdW50T2NjdXJhbmNlcyhBLCBzaXplICwga2V5KSA8PCBlbmRsOwoKICAgIGtleSA9IDM7CiAgICBjb3V0IDw8IENvdW50T2NjdXJhbmNlcyhBLCBzaXplICwga2V5KSA8PCBlbmRsOwoKICAgIC8vIFVuc3VjY2Vzc2Z1bCBjYXNlCiAgICBrZXkgPSA0OwogICAgY291dCA8PCBDb3VudE9jY3VyYW5jZXMoQSwgc2l6ZSAsIGtleSkgPDwgZW5kbDsKICAgIAogICAgcmV0dXJuIDA7Cn0K