D. Buying gifts

D. Buying gifts

Little Sasha has two friends, whom he wants to please with gifts on the Eighth of March. To do this, he went to the largest shopping center in the city.

There are n departments in the mall, each of which has exactly two stores. For convenience, we number the departments with integers from 1 to n. It is known that gifts in the first store of the i department cost ai rubles, and in the second store of the i department — bi rubles.

Entering the mall, Sasha will visit each of the n departments of the mall, and in each department, he will enter exactly one store. When Sasha gets into the i-th department, he will perform exactly one of two actions:

  1. Buy a gift for the first friend, spending ai rubles on it.
  2. Buy a gift for the second friend, spending bi rubles on it.

Sasha is going to buy at least one gift for each friend. Moreover, he wants to pick up gifts in such a way that the price difference of the most expensive gifts bought for friends is as small as possible so that no one is offended.

More formally: let m1 be the maximum price of a gift bought to the first friend, and m2 be the maximum price of a gift bought to the second friend. Sasha wants to choose gifts in such a way as to minimize the value of |m1m2|.

Input

Each test contains multiple test cases. The first line contains the number of test cases t (1t1000). The description of the test cases follows.

The first line of each test case contains a single integer n (2n500000) — the number of departments in the mall.

Each of the following n lines of each test case contains two integers ai and bi (0ai,bi109) — the prices of gifts in the first and second store of the i department, respectively.

It is guaranteed that the sum of n over all test cases does not exceed 500000.

Output

Print one integer — the minimum price difference of the most expensive gifts bought to friends.

Example

input

复制代码
2
2
1 2
2 1
5
1 5
2 7
3 3
4 10
2 5
复制代码

output

0
1

Note

In the first test case, Sasha has two possible options: buy a gift for the first friend in the first department, and the second friend — in the second department, or vice versa. In the first case, m1=m2=1, and in the second case — m1=m2=2. In both cases, the answer is 0. In the second test case, you can buy gifts for the first friend in the 2, 4 and 5 departments, and for the second friend — in the 1 and 3 departments.So m1=max(2,4,2)=4, m2=max(5,3)=5. The answer is |45|=1.

 

解题思路

  比赛时被C题搞到心态爆炸,导致后面看D题时很浮躁。其实D题比C题简单多了,比赛最后10多分钟想到怎么做,但被边界卡住,比赛结束几分钟后才做出来。

  反正我一开始是随便猜个做法,发现对a从大到小排序,然后枚举第一个人收到礼物的最大值,假设为ai,由于a是从大到小排序,因此第一个人绝对不会收到a[0i1]中的礼物,且必定会收到礼物ai。与之相对的,第二个人必定会收到b[0i1]中的所有礼物(因为题目规定每个商店都必定要买一个礼物,既然不能买给第一个人,那么必定是买给第二个人的),且必定不会收到bi

  那排序后的第j[i+1,n1]家商店的礼物呢?由于此时已把第1i1家商店的礼物购买给第二个人,不妨设其中的最大值为m=max1j<i{bj},那么此时已经有答案|aim|。对于所有bjm的商店既可以买给第一个人,也可以买给第二个人,都不会影响第一个人收到礼物的最大值ai,同时也不会影响答案|aim|。而对于bj>m的商店,如果购买给第二个人则会影响到最大值m,因此会影响到答案。所以对于bj>m的商店我们要选择性的购买给第二个人。因此我们贪心地想能否构造一组购买方案使得第二个人拥有礼物的最大值mai相差尽可能小呢?

  为此我们可以在b[i+1,n1]中找到满足xai的最大的数x,以及满足yai的最小的数y。如果选择购买x给第二个人,那么两人最大值的差值就是|aimax{m,x}|;如果选择购买y给第二个人,那么两人最大值的差值就是|aimax{m,y}|。因此对这两种情况取个最小值min{|aimax{m,x}|, |aimax{m,y}|},就是当第一个人收到礼物的最大值为ai时,两人收到礼物最大值的差值的最小值。

  因此可以枚举0n1来找到所有情况的最小值。其中开个平衡树来维护b[i+1n1],开个变量来维护b[0i1]这个前缀最大值。

  边界处理见代码注释。

  AC代码如下,时间复杂度为O(nlogn)

复制代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 
 6 const int N = 5e5 + 10, INF = 0x3f3f3f3f;
 7 
 8 int a[N], b[N], p[N];
 9 
10 void solve() {
11     int n;
12     scanf("%d", &n);
13     for (int i = 0; i < n; i++) {
14         scanf("%d %d", a + i, b + i);
15         p[i] = i;
16     }
17     sort(p, p + n, [&](int i, int j) {    // 根据a[i]从大到小排序 
18         return a[i] > a[j];
19     });
20     multiset<int> st({-INF, INF});    // 插入哨兵,保证每次在平衡树中查找x和y时一定能找到值 
21     for (int i = 0; i < n; i++) {    // 一开始先把b[0~n-1]插入平衡树中 
22         st.insert(b[i]);
23     }
24     int ret = 2e9, maxv = -INF;    // maxv是维护数组b的前缀最大值,一开始先设为-INF。当i=0,很明显第二个人只能收到第p[1]~p[n-1]个商店的礼物,设为-INF不影响答案的求值 
25     for (int i = 0; i < n; i++) {
26         st.erase(st.find(b[p[i]]));    // 把a[p[i]]买给第一个人,从平衡树中删除b[p[i]] 
27         ret = min({ret, abs(a[p[i]] - max(*st.lower_bound(a[p[i]]), maxv)), abs(a[p[i]] - max(*prev(st.upper_bound(a[p[i]])), maxv))});
28         maxv = max(maxv, b[p[i]]);    // 第二个人收到b[0~i]中的所有礼物 
29     }
30     printf("%d\n", ret);
31 }
32 
33 int main() {
34     int t;
35     scanf("%d", &t);
36     while (t--) {
37         solve();
38     }
39     
40     return 0;
41 }
复制代码

 

参考资料

  Codeforces Round #857 Editorial:https://codeforces.com/blog/entry/113857

posted @   onlyblues  阅读(282)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示