class Solution {
public:
    bool isRectangleCover(vector<vector<int>>& rectangles) {
        int left = INT_MAX, top = INT_MIN, bottom = INT_MAX, right = INT_MIN, area = 0;
        set<string> corners;
        for(auto rect : rectangles)
        {
            left = min(left, rect[0]);
            bottom = min(bottom, rect[1]);
            right = max(right, rect[2]);
            top = max(top, rect[3]);
            
            int currArea = (rect[2] - rect[0]) * (rect[3] - rect[1]);
            area += currArea;
            
            string bl = to_string(rect[0]) + "," + to_string(rect[1]);
            string br = to_string(rect[2]) + "," + to_string(rect[1]);
            string tr = to_string(rect[2]) + "," + to_string(rect[3]);
            string tl = to_string(rect[0]) + "," + to_string(rect[3]);
            
            add(corners, bl);
            add(corners, br);
            add(corners, tr);
            add(corners, tl);
        }
        
        string corner1 = to_string(left) + "," + to_string(bottom);
        string corner2 = to_string(left) + "," + to_string(top);
        string corner3 = to_string(right) + "," + to_string(bottom);
        string corner4 = to_string(right) + "," + to_string(top);
        return corners.size() == 4 && corners.find(corner1) != corners.end() && corners.find(corner2) != corners.end()&& corners.find(corner3) != corners.end() && corners.find(corner4) != corners.end() && area == (right - left) * (top - bottom);
    }

private:
    void add(set<string>& set, string point)
    {
        if(set.find(point) == set.end())set.insert(point);
        else set.erase(point);
    }
};