• POJ


    其实我最开始没有这道题。。。是做到UPC-11079-小P的决斗,训练结束后然后搜索了一波,才了解这个题的。

    非常牛逼的题。。。这么多人做出来了。。。我好菜。。。

    对于每对三元组Ta=(La,Ja,Ka),Tb=(Lb,Jb,Kb),定义Ta,Tb之间的差值D为D(Ta,Tb)=max(La−Lb,Ja−Jb,Ka−Kb)−min(La−Lb,Ja−Jb,Ka−Kb),

    给多个三元组,求两两之间差值之和。

    给出一个转化 max,min与绝对值之间的转化:

    max(a,b,c)-min(a,b,c)=(|a-b|+|b-c|+|c-a|)/2

    证明这个式子:给定一个递增的序列,a1,a2,a3,a4...an

     max(a1,a2,a3...an)-min(a1,a2,a3...an)

     =1/2(an-a1+an-a1)=an-an-1+an-1-an-2....-a2+a2-a1+an-a1

     =1/2(|an-an-1|+|an-1-an-2|+...+|a2-a1|+|a1-an|) 

    这玩意是严重对称的。。。然后。。。我也不是很清楚了

     知道这个性质以后,我们考虑一个叫贡献的东西,首先肯定把

     a=xi-yi b=yi-zi c=zi-xi  保存下来。

     首先绝对值是非常讨厌的,我们通过排序去掉了绝对值。

     然后我们考虑这样一个东西,当前是i位置,那么前面的都是比我小的,所以再对于前面i-1匹配时,a[i]做的是被减数,因此a[i]*(i-1)

      对于后面n-i-1个数,我们发现它是做减数,那么贡献其实是-(n-i)*a[i],所以单点贡献是a[i]*(i-1)-(n-i)*a[i],对与其他的也是一样的。

      

    #include<iostream>
    #include<algorithm>
    #include<string.h>
    #include<stdio.h>
    #define LL long long
    using namespace std;
    const int maxx = 500005;
    LL L[maxx];
    LL J[maxx];
    LL K[maxx];
    LL a[maxx];
    LL b[maxx];
    LL c[maxx];
    int main(){
      int n;
      while(~scanf("%d",&n)&&n){
    
        for (int i=1;i<=n;i++){
            scanf("%lld%lld%lld",&L[i],&J[i],&K[i]);
            a[i]=L[i]-J[i];
            b[i]=J[i]-K[i];
            c[i]=K[i]-L[i];
        }
        sort(a+1,a+1+n);
        sort(b+1,b+1+n);
        sort(c+1,c+1+n);
        LL ans=0;
        for (int i=1;i<=n;i++){
            ans+=a[i]*(i-1)-a[i]*(n-i);
            ans+=b[i]*(i-1)-b[i]*(n-i);
            ans+=c[i]*(i-1)-c[i]*(n-i);
        }
        printf("%lld
    ",ans/2);
      }
      return 0;
    }
    有不懂欢迎咨询 QQ:1326487164(添加时记得备注)
  • 相关阅读:
    BlockingQueue(阻塞队列)详解
    异步远程调用线程池队列
    JVM中的五大内存区域划分详解及快速扫盲
    http链接管理器
    influxDB 增加
    ArcGIS的sde数据库连接
    arcgis server注册文件夹
    arcmap编辑oracle数据库
    create database connection
    发布gp服务失败
  • 原文地址:https://www.cnblogs.com/bluefly-hrbust/p/10421217.html
Copyright © 2020-2023  润新知