分析题目性质,因为操作次数无限,所以可以把所有可以交换的位置放到一起处理,对于每一个这样的连通块,肯定要把大的放前面,小的放后面。用并查集处理连通块.然后同一连通块倒序输出,就可以得到字典序最大的解,复杂度O(nlogn).

/**
 * struct Interval {
 *    int start;
 *    int end;
 * };
 */
const int N = 1e5 + 10;
int f[N], cnt[N];
vector<int> b[N];
int find(int x)
{
    if(f[x] == x) return x;
    return f[x] = find(f[x]);
}
class Solution {
public:
    /**
     * 返回最终得到的饮料排列
     * @param n int整型 饮料数
     * @param m int整型 数对的对数
     * @param a Interval类vector 牛妹的数对
     * @return int整型vector
     */
    vector<int> sequence(int n, int m, vector<Interval>& a) {
        for(int i = 1; i <= n; i ++) f[i] = i;
        for(int i = 0; i < m; i ++)
        {
            int u = find(a[i].start);
            int v = find(a[i].end);
            f[u] = v;
        }
        vector<int> ans;
        for(int i = 1; i <= n; i ++) b[find(i)].push_back(i);
        for(int i = 1; i <= n; i ++) reverse(b[i].begin(), b[i].end());
        for(int i = 1; i <= n; i ++)
        {
            int x = find(i);
            ans.push_back(b[x][cnt[x] ++]);
        }
        return ans;
        // write code here
    }
};