3244 Difference between Triplets 好题啊 有点类似求SIGMA(线段和)的题目

Difference between Triplets
Time Limit: 3000MS Memory Limit: 65536K
Total Submissions: 1825 Accepted: 460

Description

For every pair of triplets, Ta = (Ia, Ja, Ka) and Tb = (Ib, Jb, Kb), we define the difference value between Ta and Tb as follows:

 

D(Ta, Tb) = max {IaIb, JaJb, KaKb} − min {IaIb, JaJb, KaKb}

 

Now you are given N triplets, could you write a program to calculate the sum of the difference values between every unordered pair of triplets?

Input

The input consists of several test cases.
Each test case begins with a line containing an integer N, denotes the number of triplets. Assume that we number the triplets as T1, T2, ... , TN. Then, there are following N lines, each line contains three integers, giving the elements of each triplet.
A case with N = 0 indicates the end of the input.

Output

For each case, output a line with the sum of difference values between every unordered pair of triplets.

Sample Input

2
1 2 3
3 2 1
3
1 3 2
4 0 7
2 2 9
0

Sample Output

4
20

Hint

Case 1: D( T1, T2)=4
Case 2: D( T1, T2)+ D( T1, T3)+ D( T2, T3)=8+8+4=20

You can assume that N, the number of triplets in each case, will not exceed 200,000 and the elements in triplets fit into [-10 6,10 6].
The size of the input will not exceed 5 MB.
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAX = 200001;
__int64 a[MAX],b[MAX],c[MAX];
int main()
{
    int n;
    while(scanf("%d",&n)==1&&n)
    {
        for(int i=0;i<n;i++)
        {
            int x,y,z;scanf("%d%d%d",&x,&y,&z);
            a[i]=x-y;
            b[i]=y-z;
            c[i]=x-z;
        }
        sort(a,a+n);sort(b,b+n);sort(c,c+n);
        __int64 cnt=0;
        for(int i=0;i<n;i++)
        {
            cnt+=i*a[i]-(n-i-1)*a[i];
            cnt+=i*b[i]-(n-i-1)*b[i];
            cnt+=i*c[i]-(n-i-1)*c[i];
        }
        printf("%I64d/n",cnt/2);
    }
    return 0;
}
/*
数据范围非常大,枚举必然不可,需要数学方法。这个题目巧妙之处在于,模型经过了层层的包装,
要想一下子有想法还真不容易。既然不能枚举了,这个max和min操作就不好办了,应该设法去掉。
max{a, b, c} - min{a, b, c} = |a - b| + |b - c| + | c - a| / 2,这个公式应该不难想到,
但是这只是第一步,因为引进了绝对值,依然不好做。可以先算出分子,最后再除2。
接下来需要一个等价变换,以a - b为例,a - b = xi - xj - yi + yj = (xi - yi) - (xj - yj),
同理把b - c、c - a都写成这种形式。这一步变换看似作用不大,但是假设我们算出所有的xi - yi之后
(i = 0... n - 1),将其排序,会发现,对于第i个xi - yi,它前面的都比它小,后面的都比它大。
而实际上,由于求任意两个三元组的差,肯定xi - yi会和任意的xj - yj都作差的,加了绝对值后,
它对最后的结果就会贡献i个(xi - yi),n - i - 1个-(xi - yi)。同样的方法算出所有的(yi - zi)和
(zi - xi),结果就能够求出来了。算法复杂度O(n * logn)。
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值