struct cmp {
    bool operator() (pair<string, int> &p1, pair<string, int> &p2) {
        return p1.second > p2.second || (p1.second == p2.second && p1.first < p2.first); //出现次数较高或者出现次数相同字典序小的优先级高(堆顶的元素优先级最低)
    }
};
class Solution {
public:
    vector<vector<string> > topKstrings(vector<string>& strings, int k) {
        vector<vector<string> > res;
        unordered_map<string, int> umap; //用于统计字符串出现次数
        for(string &s: strings) umap[s]++; 
        priority_queue<pair<string, int>, vector<pair<string, int> >, cmp> pq; //自定义优先队列
        for(auto it = umap.begin(); it != umap.end(); it++) { //遍历无序map
            if(pq.size() < k) pq.emplace(pair<string, int> {it->first, it->second}); //当堆元素数小于k直接入堆
            else if(it->second > pq.top().second || (it->second == pq.top().second && it->first < pq.top().first)) { //否则判断是否能取出堆顶放入新元素
                pq.pop();
                pq.emplace(pair<string, int> {it->first, it->second});
            }
        }
        while(!pq.empty()) { //由优先级从小到大依次取出
            res.emplace_back(vector<string> {pq.top().first, to_string(pq.top().second)});
            pq.pop();
        }
        reverse(res.begin(), res.end()); //逆转使优先级从大到小
        return res; //返回结果
    }
};