#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