C. Heavy Intervals

C. Heavy Intervals

You have n intervals [l1,r1],[l2,r2],,[ln,rn], such that li<ri for each i, and all the endpoints of the intervals are distinct.

The i-th interval has weight ci per unit length. Therefore, the weight of the i-th interval is ci(rili).

You don't like large weights, so you want to make the sum of weights of the intervals as small as possible. It turns out you can perform all the following three operations:

  • rearrange the elements in the array l in any order;
  • rearrange the elements in the array r in any order;
  • rearrange the elements in the array c in any order.

However, after performing all of the operations, the intervals must still be valid (i.e., for each i, li<ri must hold).

What's the minimum possible sum of weights of the intervals after performing the operations?

Input

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

The first line of each test case contains a single integer n (1n105) — the number of intervals.

The second line of each test case contains n integers l1,l2,,ln (1li2105) — the left endpoints of the initial intervals.

The third line of each test case contains n integers r1,r2,,rn (li<ri2105) — the right endpoints of the initial intervals.

It is guaranteed that {l1,l2,,ln,r1,r2,,rn} are all distinct.

The fourth line of each test case contains n integers c1,c2,,cn (1ci107) — the initial weights of the intervals per unit length.

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

Output

For each test case, output a single integer: the minimum possible sum of weights of the intervals after your operations.

Example

input

2
2
8 3
12 23
100 100
4
20 1 2 5
30 4 3 10
2 3 2 3

output

2400
42

Note

In the first test case, you can make

  • l=[8,3];
  • r=[23,12];
  • c=[100,100].

In that case, there are two intervals:

  • interval [8,23] with weight 100 per unit length, and 100(238)=1500 in total;
  • interval [3,12] with weight 100 per unit length, and 100(123)=900 in total.

The sum of the weights is 2400. It can be shown that there is no configuration of final intervals whose sum of weights is less than 2400.

In the second test case, you can make

  • l=[1,2,5,20];
  • r=[3,4,10,30];
  • c=[3,3,2,2].

In that case, there are four intervals:

  • interval [1,3] with weight 3 per unit length, and 3(31)=6 in total;
  • interval [2,4] with weight 3 per unit length, and 3(42)=6 in total;
  • interval [5,10] with weight 2 per unit length, and 2(105)=10 in total;
  • interval [20,30] with weight 2 per unit length, and 2(3020)=20 in total.

The sum of the weights is 42. It can be shown that there is no configuration of final intervals whose sum of weights is less than 42.

 

解题思路

  首先为了使得分数最小,根据排序不等式应该让数组 c 以值为关键字,区间以长度为关键字,一个升序另外一个降序,然后对应项相乘并对乘积的结果求和。

  另外容易知道对于任意合法的区间构造方案(即区间的右端点大于左端点),区间的总长度是一个定值 i=1nrii=1nli。因此在这个前提下,应该如何构造区间才能使得分数最小。

  考虑例子 l=[1,2],r=[3,5],c=[1,2]。有两种构造方案,分别是 [1,3][2,5],对应的分数是 (52)1+(31)2=7。另外一种是 [1,5][2,3],对应的分数是 (51)1+(32)2=6。很明显第二种方案会更优,可以发现第一种方案中两个区间是相交的(非包含),而第二种方案的区间是包含的,可以证明把两个相交的区间变成包含关系,分数会变小。

  假设现在有两个区间 [l1,r1][l2,r2],并且满足 l1<l2<r1<r2r1r1r2l2c1c2,那么此时分数是 (r2l2)c1+(r1l1)c2(1)。将 r1r2 交换,区间变成包含关系,分数变成了 (r2l1)c1+(r1l2)c2(2)。令 (1)(2) 得到 (l2l1)(c2c1)0,得证。

  因此只要存在两个区间是非包含的相交关系,则将其变成包含关系,那么最后得到的 n 个区间中的任意两个区间都满足包含关系。要得到这些区间的方法是把所有的 liri 放到一起排序,从小到大枚举,如果发现是左端点的值,则将其压入栈中,如果是右端点的值,则与栈顶元素匹配变成一个区间,并把栈顶元素弹出(整个过程类似于括号匹配,每个右端点尽量匹配到最靠近的左端点)。最后把得到的 n 个区间按长度排序,与数组 c 对应项相乘并求和即可。

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

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 1e5 + 10;

int a[N], b[N], c[N], p[N];
int stk[N];

void solve() {
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", a + i);
    }
    for (int i = 0; i < n; i++) {
        scanf("%d", b + i);
    }
    for (int i = 0; i < n; i++) {
        scanf("%d", c + i);
    }
    sort(a, a + n);
    sort(b, b + n);
    sort(c, c + n);
    for (int i = 0, j = 0, k = 0, tp = 0; k < n; ) {
        if (i < n && a[i] < b[j]) stk[++tp] = a[i++];
        else p[k++] = b[j++] - stk[tp--];
    }
    sort(p, p + n, greater<int>());
    LL ret = 0;
    for (int i = 0; i < n; i++) {
        ret += 1ll * p[i] * c[i];
    }
    printf("%lld\n", ret);
}

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        solve();
    }
    
    return 0;
}

 

参考资料

  Editorial of Codeforces Round 917 (Div. 2):https://codeforces.com/blog/entry/123721

  Codeforces Pinely Round 3 讲解(ABCDF1):https://www.bilibili.com/BV1iG411k7vX

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