[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\n", out[i].fst, out[i].snd);

    }

    return 0;

}

时间: 2024-10-17 08:55:26

[hdu4585]离线,并查集的相关文章

CSUOJ 1601 War (离线并查集求连通块个数)

1601: War Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 130  Solved: 38 [Submit][Status][Web Board] Description AME decided to destroy CH's country. In CH' country, There are N villages, which are numbered from 1 to N. We say two village A and B ar

ACM学习历程—Hihocoder 1291 Building in Sandbox(dfs &amp;&amp; 离线 &amp;&amp; 并查集)

http://hihocoder.com/problemset/problem/1291 前几天比较忙,这次来补一下微软笔试的最后一题,这题是这次微软笔试的第四题,过的人比较少,我当时在调试B题,没时间看这一题.不过打过之前一场BestCoder的应该都会有点思路,虽然BC那题是二维,这题是三维的,但是思路应该是一样的,没错,就是离线加并查集. 正过来考虑的时候,发现第一个要求相邻块是好处理的,但是第二个要求能否到达(1000, 1000, 1000)这个条件似乎比较难判断,当时BC上的题根据题

HDU-5441 Travel 离线-并查集

Travel Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 4680    Accepted Submission(s): 1532 Problem Description Jack likes to travel around the world, but he doesn't like to wait. Now, he is t

【杭电OJ3938】【离线+并查集】

http://acm.hdu.edu.cn/showproblem.php?pid=3938 Portal Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1921    Accepted Submission(s): 955 Problem Description ZLGG found a magic theory that the b

题解报告:zoj 3261 Connections in Galaxy War(离线并查集)

Description In order to strengthen the defense ability, many stars in galaxy allied together and built many bidirectional tunnels to exchange messages. However, when the Galaxy War began, some tunnels were destroyed by the monsters from another dimen

2015 ACM/ICPC Asia Regional Changchun Online HDU - 5441 (离线+并查集)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5441 题意:给你n,m,k,代表n个城市,m条边,k次查询,每次查询输入一个x,然后让你一个城市对(u,v)满足两点之间每一条边都不超过x,问有多少对 思路:首先我想到的是dfs求出每个查询小于等于他的一个连通块,然后num*(num-1)就是答案,但是时间只有一秒,这个复杂度是5*1e8,超时了(亲身体验了) 然后我们想这个是离线的,我们可不可以由小到大来推,这样前面的贡献到后面就依然能用了,但是我们

集合问题 离线+并查集 HDU 3938

题目大意:给你n个点,m条边,q个询问,每条边有一个val,每次询问也询问一个val,定义:这样条件的两个点(u,v),使得u->v的的价值就是所有的通路中的的最长的边最短.问满足这样的点对有几个. 思路:我们先将询问和边全部都按照val排序,然后我们知道,并查集是可以用来划分集合的,所以我们就用并查集来维护每一个集合就行了. //看看会不会爆int!数组会不会少了一维! //取物问题一定要小心先手胜利的条件 #include <bits/stdc++.h> using namespac

NOJ 1044 连通 OR 不连通 (离线并查集 + hash)

连通 OR 不连通 时间限制(普通/Java) :1000 MS/ 3000 MS          运行内存限制 : 65536 KByte 总提交 : 333            测试通过 : 65 题目描述 给定一个无向图,一共n个点,请编写一个程序实现两种操作: D x y 从原图中删除连接x,y节点的边. Q x y 询问x,y节点是否连通 输入 第一行两个数n,m(5<=n<=40000,1<=m<=100000) 接下来m行,每行一对整数 x y (x,y<=

HUD 3938 protal [ 离线并查集 ]

传送们:HDU_3938 portal 思路:主要是实现处理数据,不然便超时,所谓离线处理. 还有注意,离线的姿势,用cnt+=uset[ u] *uset[ v],,如果重新处理所有的集合,重新算的话,又会超时. #include<iostream> #include<cstdio> #include<algorithm> #include<map> using namespace std; int n,m,q; int uset[10010]; int

bzoj 1015 维护连通块个数,离线并查集

水. 1 /************************************************************** 2 Problem: 1015 3 User: idy002 4 Language: C++ 5 Result: Accepted 6 Time:2072 ms 7 Memory:14796 kb 8 ****************************************************************/ 9 10 #include