LOJ - 516 DP 一般看规律 【set + 启发式合并】

传送门
题意:给你一个n个数的数组, 由若干询问,每次询问把数组中所有值为x的改为y, 求两个相同数最近的距离是多少.
思路:维护一个map 记录所有下标为x出现的位置, 每次查找更新即可.

AC Code

map<int, set<int>>mp;
int ans = 2147483647;
void dis(int id, int x){  // 更新答案
    auto it = mp[id].lower_bound(x);
    if(it != mp[id].end()) ans = min(ans, *it - x);
    if(it != mp[id].begin()) --it, ans = min(ans, x - *it);
}
void solve() {
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1 ; i <= n ; i ++) {
        int x; scanf("%d", &x);
        dis(x, i);
        mp[x].insert(i);
    }
    while(m--) {
        int x, y;
        scanf("%d%d", &x, &y);
        if (x == y) printf("%d\n", ans);
        else {
            if (sz(mp[x]) > sz(mp[y])) swap(mp[x], mp[y]);
            for (auto it : mp[x]) {  // 启发式合并, 小的往大的上面并
                dis(y, it);
                mp[y].insert(it);
            }
            mp[x].clear(); printf("%d\n", ans);
        }
    }
}

你可能感兴趣的:(STL库的应用)