✅ Production ready c++ code
Intuition\nThe problem is to compute the moving average of a data stream while excluding the smallest and largest elements to prevent extreme values from skewin
# Intuition\nThe problem is to compute the moving average of a data stream while excluding the smallest and largest elements to prevent extreme values from skewing the results. This requires maintaining a dynamic set of the most recent data points such that we can efficiently calculate the average of the middle values at any point in time.\n\n# Approach\nThe class utilizes three multisets to store different parts of the data:\n\n1. smallestElements: Stores the smallest values.\n2. middleElements: Stores the middle values whose average is calculated\n3. largestElements: Contains the largest values.\n\n# Key Operations\n1. **Inserting Data:** As new data arrives, it is first placed into smallestElements. If this set exceeds its size limit, the largest element in smallestElements is moved to middleElements, and similarly from middleElements to largestElements if needed.\n2. **Removing Data:** When data needs to be removed (as the window moves), it is taken out from the appropriate set and the sets are rebalanced just like during insertion.\n3. **Calculating Average:** The average is calculated using the sum of middleElements, divided by its size.\n\n# Complexity\n#### Time complexity:\n1. Insertion and Removal: O(log k) for each operation, where k is the number of elements within the window. This is due to the log-time complexity for insertion and deletion operations in a multiset.\n2. Rebalancing: Each rebalancing operation, moving an element between sets, also takes O(log k).\n\n#### Space complexity:\nO(m), where m is the size of the moving window. This space is used to store elements in three multisets and an array that keeps the recent elements of the stream.\n\n# Code\n```cpp []\nclass MKAverage {\n    int windowSize;                             // Total number of elements in the moving window\n    int exclusionCount;                         // Number of elements to exclude from both ends\n    int middleSectionSize;                      // Size of the middle section containing valid elements\n    int currentPosition;                        // Current insertion position in the cyclic buffer\n    long middleSectionSum;                      // Sum of elements in the middle section\n    vector<int> recentElements;                 // Cyclic buffer to store recent elements up to windowSize\n    multiset<int> smallestElements, middleElements, largestElements; // Multisets to manage window partitions\n    \n    public:\n        MKAverage(int m, int k): windowSize(m), exclusionCount(k),\n        middleSectionSize(m - 2 * k), currentPosition(0), middleSectionSum(0) {\n            recentElements.resize(m);\n        }\n        \n        void addElement(int num) {\n            // Remove the element that is sliding out of the window if the window is full\n            if (currentPosition >= windowSize)\n                removeElement(recentElements[currentPosition % windowSize]);\n            \n            // Add the new element into the data structure\n            insertElement(num);\n            // Store the new element in the cyclic buffer\n            recentElements[currentPosition % windowSize] = num;\n            currentPosition++;\n        }\n\n        void removeElement(int number) {\n            // Remove the number from the appropriate set\n            if (number <= *rbegin(smallestElements))\n                smallestElements.erase(smallestElements.find(number));\n            else if (number <= *rbegin(middleElements)) {\n                auto it = middleElements.find(number);\n                middleSectionSum -= *it;\n                middleElements.erase(it);\n            } else\n                largestElements.erase(largestElements.find(number));\n\n            // Rebalance the sets if necessary\n            if (smallestElements.size() < exclusionCount) {\n                smallestElements.insert(*begin(middleElements));\n                middleSectionSum -= *begin(middleElements);\n                middleElements.erase(begin(middleElements));\n            }\n            if (middleElements.size() < middleSectionSize) {\n                middleElements.insert(*begin(largestElements));\n                middleSectionSum += *begin(largestElements);\n                largestElements.erase(begin(largestElements));\n            }\n        }\n\n        void insertElement(int number) {\n            smallestElements.insert(number);\n            if (smallestElements.size() > exclusionCount) {\n                auto it = prev(end(smallestElements));\n                middleElements.insert(*it);\n                middleSectionSum += *it;\n                smallestElements.erase(it);\n            }\n            if (middleElements.size() > middleSectionSize) {\n                auto it = prev(end(middleElements));\n                middleSectionSum -= *it;\n                largestElements.insert(*it);\n                middleElements.erase(it);\n            }\n        }\n        \n        int calculateMKAverage() {\n            if (currentPosition < windowSize) return -1; // Not enough elements to calculate the average\n            return middleSectionSum / middleSectionSize; // Return the average of the middle section\n        }\n};\n\n/**\n * Your MKAverage object will be instantiated and called as such:\n * MKAverage* obj = new MKAverage(m, k);\n * obj->addElement(num);\n * int param_2 = obj->calculateMKAverage();\n */\n```
['C++']