• 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
  • 相关阅读:
    wex5 实战 框架拓展之2 事件派发与data刷新
    wex5 实战 框架拓展之1 公共data组件(Data)
    wex5 实战 HeidiSQL 导入Excel数据
    wex5 实战 手指触屏插件 hammer的集成与优劣
    wex5 实战 登陆帐号更换与用户id一致性
    wex5 实战 用户点评与提交设计技巧
    wex5 实战 省市县三级联动与地址薄同步
    wex5 实战 wex5与js的组件关系与执行顺序(父子与先后)
    wex5 实战 单页模式下的多页面数据同步
    [BZOJ]4237: 稻草人
  • 原文地址:https://www.cnblogs.com/galaxies/p/loj516.html
Copyright © 2020-2023  润新知