zoukankan      html  css  js  c++  java
  • [hdu4585]离线,并查集

    题意:把一些数加到集合里面,每个数有两个属性,分别是编号和值,加进去之前询问集合里面距离自己“最近”的数的编号。最近的意思是值的差的绝对值最小,如果有相等的,则取值小的。并且已知所有数的id和value都是唯一的。

    思路:把处理过程反过来,就变成了一次把一个点删除,删除可以用数组标记,而询问则转化为找某个数左边的第一个没标记的数和右边的第一个没被标记的数,由于删除是永久的,所以完全可以通过并查集来加速,标记也可以省略。


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    #pragma comment(linker, "/STACK:10240000,10240000")
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <queue>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define fst first
    #define snd second
    pair<intint> node[123456];
    int a[123456], b[6666666];
    int fa1[123456], fa2[123456];
    int getfa1(int u) { return u == fa1[u]? u : fa1[u] = getfa1(fa1[u]); }
    int getfa2(int u) { return u == fa2[u]? u : fa2[u] = getfa2(fa2[u]); }
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt""r", stdin);
    #endif // ONLINE_JUDGE
        int n;
        while (cin >> n, n) {
            vector<pair<intint> > out(n + 1);
            for (int i = 0; i <= n + 1; i ++) fa1[i] = fa2[i] = i;
            for (int i = 1; i <= n; i ++) {
                scanf("%d%d", &node[i].fst, &node[i].snd);
                a[i] = node[i].snd;
                b[a[i]] = node[i].fst;
            }
            sort(a + 1, a + 1 + n);
            for (int i = n; i > 1; i --) {
                int pos = lower_bound(a + 1, a + 1 + n, node[i].snd) - a;
                int L = getfa1(pos - 1), R = getfa2(pos + 1);
                int dif1 = 1e9, dif2 = 1e9;
                if (L > 0) dif1 = a[pos] - a[L];
                if (R <= n) dif2 = a[R] - a[pos];
                if (dif1 <= dif2) out[i] = make_pair(node[i].fst, b[a[L]]);
                else  out[i] = make_pair(node[i].fst, b[a[R]]);
                fa1[pos] = pos - 1;
                fa2[pos] = pos + 1;
            }
            out[1] = make_pair(node[1].fst, 1);
            for (int i = 1; i <= n; i ++) printf("%d %d ", out[i].fst, out[i].snd);
        }
        return 0;
    }
  • 相关阅读:
    Hystrix高可用系统容错框架,资源隔离,熔断,限流
    Leecode no.25 K 个一组翻转链表
    no.1 Web浏览器
    源码解析-JavaNIO之Buffer,Channel
    Leecode no.24 两两交换链表中的节点
    Kafka RocketMQ 是推还是拉?
    Leecode no.23 合并K个升序链表
    图解计算机底层IO过程及JavaNIO
    Leecode no.21 合并两个有序链表
    AcWing每日一题--摘花生
  • 原文地址:https://www.cnblogs.com/jklongint/p/4550717.html
Copyright © 2011-2022 走看看