zoukankan      html  css  js  c++  java
  • loj516 「LibreOJ β Round #2」DP 一般看规律

    传送门:https://loj.ac/problem/516

    【题解】

    那段代码求的是相同的数中间隔最小的值。

    离散后用set维护每个值出现次数,每次操作相当于合并两个set,这步可以启发式合并。

    加元素的时候直接找前驱和后继即可。

    学了新姿势:set中insert有返回的,可以访问.first来调用新插入元素的iterator

    # include <set>
    # include <vector>
    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int N = 1e5 + 10, M = 3e5 + 10;
    const int mod = 1e9+7, inf = 2147483647;
    
    int n, m, a[N];
    struct quest {
        int x, y;
    }q[N];
    vector<int> ps;
    set<int> s[M];
    set<int>::iterator it, it2;
    int ans[M], Ans = inf, id[M];
    
    inline int getid(int x) {
        return lower_bound(ps.begin(), ps.end(), x) - ps.begin() + 1;
    }
    
    int main() {
        cin >> n >> m;
        for (int i=1; i<=n; ++i) {
            scanf("%d", a+i);
            ps.push_back(a[i]);
        }
        for (int i=1; i<=m; ++i) {
            scanf("%d%d", &q[i].x, &q[i].y);
            ps.push_back(q[i].x); ps.push_back(q[i].y);
        }
        sort(ps.begin(), ps.end());
        ps.erase(unique(ps.begin(), ps.end()), ps.end());
        for (int i=1; i<=n; ++i) a[i] = getid(a[i]);
        for (int i=1; i<=m; ++i) q[i].x = getid(q[i].x), q[i].y = getid(q[i].y);
        for (int i=1; i<=n; ++i) s[a[i]].insert(i);
        for (int i=1; i<=ps.size(); ++i) {
            ans[i] = inf; id[i] = i;
            if(s[i].size() < 2) continue;
            for (it = s[i].begin(), it2 = ++s[i].begin(); it2 != s[i].end(); ++it, ++it2) 
                ans[i] = min(ans[i], *it2 - *it);
            Ans = min(Ans, ans[i]);
        }
        for (int i=1, X, Y, x, tans; i<=m; ++i) {
            X = q[i].x, Y = q[i].y;
            if(!s[id[X]].size()) {
                printf("%d
    ", Ans);
                continue;
            }
            if(!s[id[Y]].size()) {
                swap(id[X], id[Y]);
                printf("%d
    ", Ans);
                continue;
            }
            tans = min(ans[id[X]], ans[id[Y]]);
            if(s[id[X]].size() > s[id[Y]].size()) swap(id[X], id[Y]);
            for (it = s[id[X]].begin(); it != s[id[X]].end(); ++it) {
                x = *it;
                it2 = s[id[Y]].insert(x).first;
                ++it2;
                if(it2 != s[id[Y]].end()) tans = min(tans, *it2 - x);
                --it2;
                if(it2 != s[id[Y]].begin()) --it2, tans = min(tans, x - *it2);
            }
            s[id[X]].clear();
            ans[id[Y]] = tans;
            ans[id[X]] = inf;
            Ans = min(Ans, tans);
            printf("%d
    ", Ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ftp卡死问题
    Windows 10 安装FileZilla Server
    The last packet successfully received from the server was 39,900 milliseconds ago问题解决
    java.sql.SQLException: Could not retrieve transaction read-only status from server 问题解决
    三主机配置 keepalived VIP高可用
    subprocess.Popen在win10下会有异常
    python 使用内置方法读取注册表
    过年有感
    java.security.InvalidKeyException: Illegal key size 解决办法
    Android Studio 检查Top Activity
  • 原文地址:https://www.cnblogs.com/galaxies/p/loj516.html
Copyright © 2011-2022 走看看