• hdu 3015 Disharmony Trees


    题意:

    有若干棵树,每棵树有横坐标xi和高度hi。

    把若干棵树按照x递增排序,每棵树的rank是ri,那么定义两颗树的F为abs(ri-rj)。

    把若干棵树按照高度递增排序,每棵树的rank是ri,定义两棵树的D为min(ri,rj)。

    两棵树的不和谐度定义为D * F。

    求n棵树中任意两棵树的不和谐度的总和。

    思路:

    首先把每棵树的坐标rank和高度rank求出来。

    然后按照高度rank降序排序,对于当前的树,小于等于它的x rank的树的数量可以用树状数组维护,它们的坐标rank总和也可以用树状数组维护。

    假设前面所有树的x总和为dis,小于等于它的x rank的树的数量为cnt,它们的坐标rank总和为sum

    那么Σabs(xi - xk)(k < i)的值就是cnt * xri - sum + dis - sum - (i - cnt - 1) * xri。

    代码:

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <algorithm>
      4 using namespace std;
      5 const int N = 1e5 + 10;
      6 int n;
      7 int c[N];
      8 long long sum[N];
      9 struct node
     10 {
     11     int x,h;
     12     int xr,hr;     
     13 } a[N];
     14 bool cmp1(node aa,node bb)
     15 {
     16     return aa.x < bb.x;
     17 }
     18 bool cmp2(node aa,node bb)
     19 {
     20     return aa.h < bb.h;
     21 }
     22 bool cmp3(node aa,node bb)
     23 {
     24     return aa.hr > bb.hr;
     25 }
     26 int lowbit(int x)
     27 {
     28     return x&(-x);
     29 }
     30 void addcnt(int x)
     31 {
     32     for (int i = x;i <= n;i += lowbit(i)) c[i]++;
     33 }
     34 void addsum(int x,int y)
     35 {
     36     for (int i = x;i <= n;i += lowbit(i)) sum[i] += y;
     37 }
     38 int getcnt(int x)
     39 {
     40     int ans = 0;
     41     for (int i = x;i > 0;i -= lowbit(i)) ans += c[i];
     42     return ans; 
     43 }
     44 long long getsum(int x)
     45 {
     46     long long ans = 0;
     47     for (int i = x;i > 0; i-= lowbit(i)) ans += sum[i];
     48     return ans;
     49 }
     50 int main()
     51 {
     52     
     53     while (scanf("%d",&n) != EOF)
     54     {
     55         memset(c,0,sizeof(c));
     56         memset(sum,0,sizeof(sum));
     57         for (int i = 1;i <= n;i++)
     58         {
     59             scanf("%d%d",&a[i].x,&a[i].h);
     60         }
     61         sort(a+1,a+1+n,cmp1);
     62         for (int i = 1;i <= n;i++)
     63         {
     64             if (i == 1)
     65             {
     66                 a[i].xr = 1;
     67             }
     68             else
     69             {
     70                 if (a[i].x == a[i-1].x)
     71                 {
     72                     a[i].xr = a[i-1].xr;
     73                 }
     74                 else
     75                 {
     76                     a[i].xr = i;
     77                 }
     78             }
     79         }
     80         sort(a+1,a+1+n,cmp2);
     81         for (int i = 1;i <= n;i++)
     82         {
     83             if (i == 1)
     84             {
     85                 a[i].hr = 1;
     86             }
     87             else
     88             {
     89                 if (a[i].h == a[i-1].h)
     90                 {
     91                     a[i].hr = a[i-1].hr;
     92                 }
     93                 else
     94                 {
     95                     a[i].hr = i;
     96                 }
     97             }
     98         }
     99         sort(a+1,a+1+n,cmp3);
    100         long long dis = 0;
    101         long long ans = 0;
    102         for (int i = 1;i <= n;i++)
    103         {
    104             int cnt = getcnt(a[i].xr);
    105             long long su = getsum(a[i].xr);
    106             long long res = 1LL * cnt * a[i].xr - su;
    107             res += dis - su - 1LL * (i - cnt - 1) * a[i].xr;
    108             ans += res * a[i].hr;
    109             addcnt(a[i].xr);
    110             addsum(a[i].xr,a[i].xr);
    111             dis += a[i].xr;
    112             
    113         }
    114         printf("%lld
    ",ans);
    115     }
    116     return 0;
    117 }
  • 相关阅读:
    opensuse字符和图形界面
    Eclipse编辑器小手段
    切换运行时用户以及用户组
    PHP安装和配置
    Linux程序资源限制简述
    test2234343
    找回Svn和Git不见的文件图标
    SourceInsight使用技巧
    Javascript数组使用方法
    MySQL安装和配置
  • 原文地址:https://www.cnblogs.com/kickit/p/9077771.html
Copyright © 2020-2023  润新知